diff --git a/app/src/amazon/java/org/tasks/FlavorSetup.java b/app/src/amazon/java/org/tasks/FlavorSetup.java
index 8f7b2739c..08cc80bdd 100644
--- a/app/src/amazon/java/org/tasks/FlavorSetup.java
+++ b/app/src/amazon/java/org/tasks/FlavorSetup.java
@@ -1,21 +1,13 @@
package org.tasks;
import javax.inject.Inject;
-import org.tasks.preferences.Preferences;
public class FlavorSetup {
- private final CaldavAccountManager caldavAccountManager;
- private final Preferences preferences;
-
@Inject
- public FlavorSetup(CaldavAccountManager caldavAccountManager, Preferences preferences) {
- this.caldavAccountManager = caldavAccountManager;
- this.preferences = preferences;
+ public FlavorSetup() {
}
public void setup() {
- caldavAccountManager
- .setBackgroundSynchronization(preferences.getBoolean(R.string.p_background_sync, true));
}
}
diff --git a/app/src/androidTestGoogleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapterTest.java b/app/src/androidTestGoogleplay/java/org/tasks/gtasks/GoogleTaskSynchronizerTest.java
similarity index 96%
rename from app/src/androidTestGoogleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapterTest.java
rename to app/src/androidTestGoogleplay/java/org/tasks/gtasks/GoogleTaskSynchronizerTest.java
index 62cc180d3..a49896270 100644
--- a/app/src/androidTestGoogleplay/java/org/tasks/gtasks/GoogleTaskSyncAdapterTest.java
+++ b/app/src/androidTestGoogleplay/java/org/tasks/gtasks/GoogleTaskSynchronizerTest.java
@@ -4,7 +4,7 @@ import static com.natpryce.makeiteasy.MakeItEasy.with;
import static com.todoroo.astrid.data.Task.HIDE_UNTIL_DUE;
import static com.todoroo.astrid.data.Task.HIDE_UNTIL_DUE_TIME;
import static junit.framework.Assert.assertEquals;
-import static org.tasks.gtasks.GoogleTaskSyncAdapter.mergeDates;
+import static org.tasks.gtasks.GoogleTaskSynchronizer.mergeDates;
import static org.tasks.makers.TaskMaker.DUE_DATE;
import static org.tasks.makers.TaskMaker.DUE_TIME;
import static org.tasks.makers.TaskMaker.HIDE_TYPE;
@@ -17,7 +17,7 @@ import org.junit.runner.RunWith;
import org.tasks.time.DateTime;
@RunWith(AndroidJUnit4.class)
-public class GoogleTaskSyncAdapterTest {
+public class GoogleTaskSynchronizerTest {
@Test
public void testMergeDate() {
diff --git a/app/src/generic/java/org/tasks/FlavorSetup.java b/app/src/generic/java/org/tasks/FlavorSetup.java
index 8f7b2739c..08cc80bdd 100644
--- a/app/src/generic/java/org/tasks/FlavorSetup.java
+++ b/app/src/generic/java/org/tasks/FlavorSetup.java
@@ -1,21 +1,13 @@
package org.tasks;
import javax.inject.Inject;
-import org.tasks.preferences.Preferences;
public class FlavorSetup {
- private final CaldavAccountManager caldavAccountManager;
- private final Preferences preferences;
-
@Inject
- public FlavorSetup(CaldavAccountManager caldavAccountManager, Preferences preferences) {
- this.caldavAccountManager = caldavAccountManager;
- this.preferences = preferences;
+ public FlavorSetup() {
}
public void setup() {
- caldavAccountManager
- .setBackgroundSynchronization(preferences.getBoolean(R.string.p_background_sync, true));
}
}
diff --git a/app/src/googleplay/AndroidManifest.xml b/app/src/googleplay/AndroidManifest.xml
index a901e76a9..ac28f9431 100644
--- a/app/src/googleplay/AndroidManifest.xml
+++ b/app/src/googleplay/AndroidManifest.xml
@@ -20,14 +20,7 @@
This service is invoked in response to Intents with action android.content.SyncAdapter, and - * returns a Binder connection to SyncAdapter. - * - *
For performance, only one sync adapter will be initialized within this application's context. - * - *
Note: The SyncService itself is not notified when a new sync occurs. It's role is to manage - * the lifecycle of our {@link GoogleTaskSyncAdapter} and provide a handle to said SyncAdapter to - * the OS on request. - */ -public class GoogleTaskSyncService extends Service { - - private static final Object sSyncAdapterLock = new Object(); - private static GoogleTaskSyncAdapter sGoogleTaskSyncAdapter = null; - - /** - * Thread-safe constructor, creates static {@link GoogleTaskSyncAdapter} instance. - */ - @Override - public void onCreate() { - super.onCreate(); - Timber.d("Service created"); - synchronized (sSyncAdapterLock) { - if (sGoogleTaskSyncAdapter == null) { - sGoogleTaskSyncAdapter = new GoogleTaskSyncAdapter(getApplicationContext(), true); - } - } - } - - @Override - /** - * Logging-only destructor. - */ - public void onDestroy() { - super.onDestroy(); - Timber.d("Service destroyed"); - } - - /** - * Return Binder handle for IPC communication with {@link GoogleTaskSyncAdapter}. - * - *
New sync requests will be sent directly to the SyncAdapter using this channel. - * - * @param intent Calling intent - * @return Binder handle for {@link GoogleTaskSyncAdapter} - */ - @Override - public IBinder onBind(Intent intent) { - return sGoogleTaskSyncAdapter.getSyncAdapterBinder(); - } -} diff --git a/app/src/main/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java b/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java similarity index 79% rename from app/src/main/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java rename to app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java index 14aa7db2e..53178132b 100644 --- a/app/src/main/java/org/tasks/gtasks/GoogleTaskSyncAdapter.java +++ b/app/src/main/java/org/tasks/gtasks/GoogleTaskSynchronizer.java @@ -1,30 +1,10 @@ -/* - * Copyright 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package org.tasks.gtasks; import static org.tasks.date.DateTimeUtils.newDateTime; -import android.accounts.Account; import android.app.PendingIntent; -import android.content.ContentProviderClient; import android.content.Context; import android.content.Intent; -import android.content.SyncResult; -import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; @@ -59,8 +39,7 @@ import org.tasks.data.GoogleTask; import org.tasks.data.GoogleTaskDao; import org.tasks.data.GoogleTaskList; import org.tasks.data.GoogleTaskListDao; -import org.tasks.injection.InjectingAbstractThreadedSyncAdapter; -import org.tasks.injection.SyncAdapterComponent; +import org.tasks.injection.ForApplication; import org.tasks.notifications.NotificationManager; import org.tasks.preferences.DefaultFilterProvider; import org.tasks.preferences.Preferences; @@ -68,36 +47,49 @@ import org.tasks.sync.RecordSyncStatusCallback; import org.tasks.time.DateTime; import timber.log.Timber; -/** - * Define a sync adapter for the app. - * - *
This class is instantiated in {@link GoogleTaskSyncService}, which also binds SyncAdapter to - * the system. SyncAdapter should only be initialized in SyncService, never anywhere else. - * - *
The system calls onPerformSync() via an RPC call through the IBinder object supplied by - * SyncService. - */ -public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter { +public class GoogleTaskSynchronizer { private static final String DEFAULT_LIST = "@default"; //$NON-NLS-1$ - @Inject GtasksPreferenceService gtasksPreferenceService; - @Inject LocalBroadcastManager localBroadcastManager; - @Inject GoogleTaskListDao googleTaskListDao; - @Inject GtasksSyncService gtasksSyncService; - @Inject GtasksListService gtasksListService; - @Inject GtasksTaskListUpdater gtasksTaskListUpdater; - @Inject Preferences preferences; - @Inject GtasksInvoker gtasksInvoker; - @Inject TaskDao taskDao; - @Inject Tracker tracker; - @Inject NotificationManager notificationManager; - @Inject GoogleTaskDao googleTaskDao; - @Inject TaskCreator taskCreator; - @Inject DefaultFilterProvider defaultFilterProvider; - - public GoogleTaskSyncAdapter(Context context, boolean autoInitialize) { - super(context, autoInitialize); + private final Context context; + private final GtasksPreferenceService gtasksPreferenceService; + private final LocalBroadcastManager localBroadcastManager; + private final GoogleTaskListDao googleTaskListDao; + private final GtasksSyncService gtasksSyncService; + private final GtasksListService gtasksListService; + private final GtasksTaskListUpdater gtasksTaskListUpdater; + private final Preferences preferences; + private final GtasksInvoker gtasksInvoker; + private final TaskDao taskDao; + private final Tracker tracker; + private final NotificationManager notificationManager; + private final GoogleTaskDao googleTaskDao; + private final TaskCreator taskCreator; + private final DefaultFilterProvider defaultFilterProvider; + + @Inject + public GoogleTaskSynchronizer(@ForApplication Context context, + GtasksPreferenceService gtasksPreferenceService, LocalBroadcastManager localBroadcastManager, + GoogleTaskListDao googleTaskListDao, GtasksSyncService gtasksSyncService, + GtasksListService gtasksListService, GtasksTaskListUpdater gtasksTaskListUpdater, + Preferences preferences, GtasksInvoker gtasksInvoker, TaskDao taskDao, Tracker tracker, + NotificationManager notificationManager, GoogleTaskDao googleTaskDao, TaskCreator taskCreator, + DefaultFilterProvider defaultFilterProvider) { + this.context = context; + this.gtasksPreferenceService = gtasksPreferenceService; + this.localBroadcastManager = localBroadcastManager; + this.googleTaskListDao = googleTaskListDao; + this.gtasksSyncService = gtasksSyncService; + this.gtasksListService = gtasksListService; + this.gtasksTaskListUpdater = gtasksTaskListUpdater; + this.preferences = preferences; + this.gtasksInvoker = gtasksInvoker; + this.taskDao = taskDao; + this.tracker = tracker; + this.notificationManager = notificationManager; + this.googleTaskDao = googleTaskDao; + this.taskCreator = taskCreator; + this.defaultFilterProvider = defaultFilterProvider; } public static void mergeDates(long remoteDueDate, Task local) { @@ -114,26 +106,9 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter } } - /** - * Called by the Android system in response to a request to run the sync adapter. The work - * required to read data from the network, parse it, and store it in the content provider is done - * here. Extending AbstractThreadedSyncAdapter ensures that all methods within SyncAdapter run on - * a background thread. For this reason, blocking I/O and other long-running tasks can be run - * in situ, and you don't have to set up a separate thread for them. . - * - *
This is where we actually perform any work required to perform a sync. {@link - * android.content.AbstractThreadedSyncAdapter} guarantees that this will be called on a non-UI - * thread, so it is safe to peform blocking I/O here. - * - *
The syncResult argument allows you to pass information back to the method that triggered the - * sync. - */ - @Override - public void onPerformSync(Account account, Bundle extras, String authority, - ContentProviderClient provider, SyncResult syncResult) { - if (!account.name.equals(gtasksPreferenceService.getUserName())) { - Timber.d("Sync not enabled for %s", account); - syncResult.stats.numAuthExceptions++; + public void sync() { + String account = gtasksPreferenceService.getUserName(); + if (TextUtils.isEmpty(account)) { return; } Timber.d("%s: start sync", account); @@ -145,7 +120,7 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter gtasksPreferenceService.recordSuccessfulSync(); } catch (UserRecoverableAuthIOException e) { Timber.e(e, e.getMessage()); - sendNotification(getContext(), e.getIntent()); + sendNotification(context, e.getIntent()); } catch (IOException e) { Timber.e(e, e.getMessage()); } catch (Exception e) { @@ -215,9 +190,6 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter } } - /** - * Synchronize with server when data changes - */ private void pushTask(Task task, GtasksInvoker invoker) throws IOException { for (GoogleTask deleted : googleTaskDao.getDeletedByTaskId(task.getId())) { gtasksInvoker.deleteGtask(deleted.getListId(), deleted.getRemoteId()); @@ -422,9 +394,4 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter googleTaskDao.insert(values); } } - - @Override - protected void inject(SyncAdapterComponent component) { - component.inject(this); - } } diff --git a/app/src/main/java/org/tasks/gtasks/GtaskSyncAdapterHelper.java b/app/src/main/java/org/tasks/gtasks/GtaskSyncAdapterHelper.java index fcd77d732..6454bc1e6 100644 --- a/app/src/main/java/org/tasks/gtasks/GtaskSyncAdapterHelper.java +++ b/app/src/main/java/org/tasks/gtasks/GtaskSyncAdapterHelper.java @@ -28,38 +28,6 @@ public class GtaskSyncAdapterHelper { this.tracker = tracker; } - /** - * Helper method to trigger an immediate sync ("refresh"). - * - *
This should only be used when we need to preempt the normal sync schedule. Typically, this
- * means the user has pressed the "refresh" button.
- *
- * Note that SYNC_EXTRAS_MANUAL will cause an immediate sync, without any optimization to
- * preserve battery life. If you know new data is available (perhaps via a GCM notification),
- * but the user is not actively waiting for that data, you should omit this flag; this will give
- * the OS additional freedom in scheduling your sync request.
- */
- public boolean initiateManualSync() {
- Account account = getAccount();
- if (account == null) {
- return false;
- }
- Bundle extras = new Bundle();
- // Disable sync backoff and ignore sync preferences. In other words...perform sync NOW!
- extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
- extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
- ContentResolver.requestSync(account, AUTHORITY, extras);
- return true;
- }
-
- public void requestSynchronization() {
- Account account = getAccount();
- if (account == null) {
- return;
- }
- ContentResolver.requestSync(account, AUTHORITY, new Bundle());
- }
-
public boolean isEnabled() {
return preferences.getBoolean(R.string.sync_gtasks, false) &&
playServices.isPlayServicesAvailable() &&
diff --git a/app/src/main/java/org/tasks/injection/ApplicationComponent.java b/app/src/main/java/org/tasks/injection/ApplicationComponent.java
index 2b397ac69..f59ece469 100644
--- a/app/src/main/java/org/tasks/injection/ApplicationComponent.java
+++ b/app/src/main/java/org/tasks/injection/ApplicationComponent.java
@@ -9,8 +9,6 @@ import org.tasks.widget.ScrollableWidgetUpdateService;
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {
- SyncAdapterComponent plus(SyncAdapterModule syncAdapterModule);
-
void inject(DashClockExtension dashClockExtension);
void inject(Tasks tasks);
diff --git a/app/src/main/java/org/tasks/injection/InjectingAbstractThreadedSyncAdapter.java b/app/src/main/java/org/tasks/injection/InjectingAbstractThreadedSyncAdapter.java
deleted file mode 100644
index 4793b222d..000000000
--- a/app/src/main/java/org/tasks/injection/InjectingAbstractThreadedSyncAdapter.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.tasks.injection;
-
-import android.content.AbstractThreadedSyncAdapter;
-import android.content.Context;
-
-public abstract class InjectingAbstractThreadedSyncAdapter extends AbstractThreadedSyncAdapter {
-
- protected InjectingAbstractThreadedSyncAdapter(Context context, boolean autoInitialize) {
- super(context, autoInitialize);
- inject(context);
- }
-
- private void inject(Context context) {
- inject(Dagger.get(context)
- .getApplicationComponent()
- .plus(new SyncAdapterModule()));
- }
-
- protected abstract void inject(SyncAdapterComponent component);
-}
diff --git a/app/src/main/java/org/tasks/injection/SyncAdapterComponent.java b/app/src/main/java/org/tasks/injection/SyncAdapterComponent.java
deleted file mode 100644
index 8d579c96e..000000000
--- a/app/src/main/java/org/tasks/injection/SyncAdapterComponent.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.tasks.injection;
-
-import dagger.Subcomponent;
-import org.tasks.gtasks.GoogleTaskSyncAdapter;
-
-@Subcomponent(modules = SyncAdapterModule.class)
-public interface SyncAdapterComponent {
-
- void inject(GoogleTaskSyncAdapter googleTaskSyncAdapter);
-}
diff --git a/app/src/main/java/org/tasks/injection/SyncAdapterModule.java b/app/src/main/java/org/tasks/injection/SyncAdapterModule.java
deleted file mode 100644
index 194af4f4e..000000000
--- a/app/src/main/java/org/tasks/injection/SyncAdapterModule.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.tasks.injection;
-
-import dagger.Module;
-
-@Module
-public class SyncAdapterModule {
-
-}
diff --git a/app/src/main/java/org/tasks/jobs/CaldavSyncJob.java b/app/src/main/java/org/tasks/jobs/CaldavSyncJob.java
deleted file mode 100644
index 6988537cd..000000000
--- a/app/src/main/java/org/tasks/jobs/CaldavSyncJob.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.tasks.jobs;
-
-import android.support.annotation.NonNull;
-import com.evernote.android.job.Job;
-import org.tasks.caldav.CaldavSynchronizer;
-
-public class CaldavSyncJob extends Job{
-
- private final CaldavSynchronizer caldavSynchronizer;
-
- CaldavSyncJob(CaldavSynchronizer caldavSynchronizer) {
- this.caldavSynchronizer = caldavSynchronizer;
- }
-
- @NonNull
- @Override
- protected Result onRunJob(@NonNull Params params) {
- return caldavSynchronizer.sync() ? Result.SUCCESS : Result.FAILURE;
- }
-}
diff --git a/app/src/main/java/org/tasks/jobs/JobCreator.java b/app/src/main/java/org/tasks/jobs/JobCreator.java
index 717f9032b..802a3cd8f 100644
--- a/app/src/main/java/org/tasks/jobs/JobCreator.java
+++ b/app/src/main/java/org/tasks/jobs/JobCreator.java
@@ -9,6 +9,7 @@ import org.tasks.LocalBroadcastManager;
import org.tasks.Notifier;
import org.tasks.backup.TasksJsonExporter;
import org.tasks.caldav.CaldavSynchronizer;
+import org.tasks.gtasks.GoogleTaskSynchronizer;
import org.tasks.injection.ApplicationScope;
import org.tasks.injection.ForApplication;
import org.tasks.preferences.Preferences;
@@ -25,18 +26,19 @@ public class JobCreator implements com.evernote.android.job.JobCreator {
private final RefreshScheduler refreshScheduler;
private final LocalBroadcastManager localBroadcastManager;
private final CaldavSynchronizer caldavSynchronizer;
+ private final GoogleTaskSynchronizer googleTaskSynchronizer;
static final String TAG_BACKUP = "tag_backup";
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_CALDAV_SYNC = "tag_caldav_sync";
+ static final String TAG_SYNC = "tag_sync";
@Inject
public JobCreator(@ForApplication Context context, Preferences preferences, Notifier notifier,
NotificationQueue notificationQueue, TasksJsonExporter tasksJsonExporter,
RefreshScheduler refreshScheduler, LocalBroadcastManager localBroadcastManager,
- CaldavSynchronizer caldavSynchronizer) {
+ CaldavSynchronizer caldavSynchronizer, GoogleTaskSynchronizer googleTaskSynchronizer) {
this.context = context;
this.preferences = preferences;
this.notifier = notifier;
@@ -45,6 +47,7 @@ public class JobCreator implements com.evernote.android.job.JobCreator {
this.refreshScheduler = refreshScheduler;
this.localBroadcastManager = localBroadcastManager;
this.caldavSynchronizer = caldavSynchronizer;
+ this.googleTaskSynchronizer = googleTaskSynchronizer;
}
@Nullable
@@ -53,8 +56,8 @@ public class JobCreator implements com.evernote.android.job.JobCreator {
switch (tag) {
case TAG_NOTIFICATION:
return new NotificationJob(preferences, notifier, notificationQueue);
- case TAG_CALDAV_SYNC:
- return new CaldavSyncJob(caldavSynchronizer);
+ case TAG_SYNC:
+ return new SyncJob(caldavSynchronizer, googleTaskSynchronizer);
case TAG_BACKUP:
return new BackupJob(context, tasksJsonExporter, preferences);
case TAG_MIDNIGHT_REFRESH:
diff --git a/app/src/main/java/org/tasks/jobs/JobManager.java b/app/src/main/java/org/tasks/jobs/JobManager.java
index 29bc6bcea..586dde6c0 100644
--- a/app/src/main/java/org/tasks/jobs/JobManager.java
+++ b/app/src/main/java/org/tasks/jobs/JobManager.java
@@ -1,5 +1,6 @@
package org.tasks.jobs;
+import static android.text.TextUtils.isEmpty;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import static org.tasks.time.DateTimeUtils.printTimestamp;
@@ -7,9 +8,12 @@ import com.evernote.android.job.DailyJob;
import com.evernote.android.job.JobRequest;
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.inject.Inject;
+import org.tasks.R;
import org.tasks.injection.ApplicationScope;
+import org.tasks.preferences.Preferences;
import timber.log.Timber;
@ApplicationScope
@@ -24,10 +28,12 @@ public class JobManager {
public static final int JOB_ID_TASKER = 11;
private final com.evernote.android.job.JobManager jobManager;
+ private final Preferences preferences;
@Inject
- public JobManager(com.evernote.android.job.JobManager jobManager) {
+ public JobManager(com.evernote.android.job.JobManager jobManager, Preferences preferences) {
this.jobManager = jobManager;
+ this.preferences = preferences;
}
public void scheduleNotification(long time) {
@@ -57,9 +63,23 @@ public class JobManager {
TimeUnit.HOURS.toMillis(24) - 1);
}
- public void setBackgroundSynchronization(boolean enabled) {
+ public void updateBackgroundSync() {
+ updateBackgroundSync(false, false);
+ }
+
+ 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);
+ }
+
+ private void scheduleBackgroundSynchronization(boolean enabled) {
+ Timber.d("background sync enabled: %s", enabled);
if (enabled) {
- new JobRequest.Builder(JobCreator.TAG_CALDAV_SYNC)
+ new JobRequest.Builder(JobCreator.TAG_SYNC)
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequirementsEnforced(true)
.setPeriodic(TimeUnit.HOURS.toMillis(1))
@@ -67,18 +87,17 @@ public class JobManager {
.build()
.schedule();
} else {
- jobManager.cancelAllForTag(JobCreator.TAG_CALDAV_SYNC);
+ jobManager.cancelAllForTag(JobCreator.TAG_SYNC);
}
}
- public boolean syncCaldavNow() {
- new JobRequest.Builder(JobCreator.TAG_CALDAV_SYNC)
+ public void syncNow() {
+ new JobRequest.Builder(JobCreator.TAG_SYNC)
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequirementsEnforced(true)
.setExecutionWindow(1, 5000)
.build()
.schedule();
- return true;
}
public void cancelNotifications() {
@@ -94,4 +113,8 @@ public class JobManager {
private long calculateDelay(long time) {
return Math.max(5000, time - currentTimeMillis());
}
+
+ public void addJobCreator(JobCreator jobCreator) {
+ jobManager.addJobCreator(jobCreator);
+ }
}
diff --git a/app/src/main/java/org/tasks/jobs/SyncJob.java b/app/src/main/java/org/tasks/jobs/SyncJob.java
new file mode 100644
index 000000000..8da33014a
--- /dev/null
+++ b/app/src/main/java/org/tasks/jobs/SyncJob.java
@@ -0,0 +1,25 @@
+package org.tasks.jobs;
+
+import android.support.annotation.NonNull;
+import com.evernote.android.job.Job;
+import org.tasks.caldav.CaldavSynchronizer;
+import org.tasks.gtasks.GoogleTaskSynchronizer;
+
+public class SyncJob extends Job{
+
+ private final CaldavSynchronizer caldavSynchronizer;
+ private final GoogleTaskSynchronizer googleTaskSynchronizer;
+
+ SyncJob(CaldavSynchronizer caldavSynchronizer, GoogleTaskSynchronizer googleTaskSynchronizer) {
+ this.caldavSynchronizer = caldavSynchronizer;
+ this.googleTaskSynchronizer = googleTaskSynchronizer;
+ }
+
+ @NonNull
+ @Override
+ protected Result onRunJob(@NonNull Params params) {
+ caldavSynchronizer.sync();
+ googleTaskSynchronizer.sync();
+ return Result.SUCCESS;
+ }
+}
diff --git a/app/src/main/java/org/tasks/preferences/PermissionChecker.java b/app/src/main/java/org/tasks/preferences/PermissionChecker.java
index a9405ece0..9d355b081 100644
--- a/app/src/main/java/org/tasks/preferences/PermissionChecker.java
+++ b/app/src/main/java/org/tasks/preferences/PermissionChecker.java
@@ -1,5 +1,6 @@
package org.tasks.preferences;
+import static com.todoroo.andlib.utility.AndroidUtilities.atLeastOreo;
import static com.todoroo.andlib.utility.AndroidUtilities.preJellybean;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
@@ -34,7 +35,7 @@ public class PermissionChecker {
}
public boolean canAccessAccounts() {
- return checkPermission(Manifest.permission.GET_ACCOUNTS);
+ return atLeastOreo() || checkPermission(Manifest.permission.GET_ACCOUNTS);
}
public boolean canAccessLocation() {
diff --git a/app/src/main/java/org/tasks/receivers/CalDAVPushReceiver.java b/app/src/main/java/org/tasks/receivers/CalDAVPushReceiver.java
deleted file mode 100644
index 9c25a8b33..000000000
--- a/app/src/main/java/org/tasks/receivers/CalDAVPushReceiver.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.tasks.receivers;
-
-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;
-
-public class CalDAVPushReceiver {
-
- private final JobManager jobManager;
- private final SyncAdapters syncAdapters;
-
- @Inject
- public CalDAVPushReceiver(JobManager jobManager, SyncAdapters syncAdapters) {
- this.jobManager = jobManager;
- this.syncAdapters = syncAdapters;
- }
-
- public void push(Task task, Task original) {
- if (!syncAdapters.isCaldavSyncEnabled()) {
- return;
- }
-
- if (task.checkTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) {
- return;
- }
-
- jobManager.syncCaldavNow();
- }
-}
diff --git a/app/src/main/java/org/tasks/receivers/GoogleTaskPusher.java b/app/src/main/java/org/tasks/receivers/GoogleTaskPusher.java
deleted file mode 100644
index 3a4b5ce51..000000000
--- a/app/src/main/java/org/tasks/receivers/GoogleTaskPusher.java
+++ /dev/null
@@ -1,39 +0,0 @@
-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.sync.SyncAdapters;
-
-public class GoogleTaskPusher {
-
- private final SyncAdapters syncAdapters;
-
- @Inject
- public GoogleTaskPusher(SyncAdapters syncAdapters) {
- this.syncAdapters = syncAdapters;
- }
-
- void push(Task task, Task original) {
- if (!syncAdapters.isGoogleTaskSyncEnabled()) {
- return;
- }
-
- if (task.checkTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) {
- return;
- }
-
- 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.requestSynchronization();
- }
- }
-}
diff --git a/app/src/main/java/org/tasks/receivers/PushReceiver.java b/app/src/main/java/org/tasks/receivers/PushReceiver.java
index 75511ccd3..7de714665 100644
--- a/app/src/main/java/org/tasks/receivers/PushReceiver.java
+++ b/app/src/main/java/org/tasks/receivers/PushReceiver.java
@@ -1,21 +1,63 @@
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;
public class PushReceiver {
- private final GoogleTaskPusher googleTaskPusher;
- private final CalDAVPushReceiver calDAVPushReceiver;
+ private final SyncAdapters syncAdapters;
+ private final JobManager jobManager;
@Inject
- public PushReceiver(GoogleTaskPusher googleTaskPusher, CalDAVPushReceiver calDAVPushReceiver) {
- this.googleTaskPusher = googleTaskPusher;
- this.calDAVPushReceiver = calDAVPushReceiver;
+ public PushReceiver(SyncAdapters syncAdapters, JobManager jobManager) {
+ this.syncAdapters = syncAdapters;
+ this.jobManager = jobManager;
}
public void push(Task task, Task original) {
- googleTaskPusher.push(task, original);
- calDAVPushReceiver.push(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()) {
+ return;
+ }
+
+ if (task.checkTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) {
+ return;
+ }
+
+ jobManager.syncNow();
}
}
diff --git a/app/src/main/java/org/tasks/sync/SyncAdapters.java b/app/src/main/java/org/tasks/sync/SyncAdapters.java
index 8ca434675..4ea3982b6 100644
--- a/app/src/main/java/org/tasks/sync/SyncAdapters.java
+++ b/app/src/main/java/org/tasks/sync/SyncAdapters.java
@@ -22,17 +22,12 @@ public class SyncAdapters {
this.jobManager = jobManager;
}
- public void requestSynchronization() {
- gtaskSyncAdapterHelper.requestSynchronization();
- jobManager.syncCaldavNow();
- }
-
- public boolean initiateManualSync() {
- return gtaskSyncAdapterHelper.initiateManualSync() | jobManager.syncCaldavNow();
- }
-
- public boolean isMasterSyncEnabled() {
- return ContentResolver.getMasterSyncAutomatically();
+ public boolean syncNow() {
+ if (isGoogleTaskSyncEnabled() || isCaldavSyncEnabled()) {
+ jobManager.syncNow();
+ return true;
+ }
+ return false;
}
public boolean isSyncEnabled() {
diff --git a/app/src/main/java/org/tasks/sync/SynchronizationPreferences.java b/app/src/main/java/org/tasks/sync/SynchronizationPreferences.java
index a186fb981..73ab3eb5b 100644
--- a/app/src/main/java/org/tasks/sync/SynchronizationPreferences.java
+++ b/app/src/main/java/org/tasks/sync/SynchronizationPreferences.java
@@ -60,8 +60,7 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
caldavEnabled.setChecked(syncAdapters.isCaldavSyncEnabled());
caldavEnabled.setOnPreferenceChangeListener((preference, newValue) -> {
boolean enabled = ((boolean) newValue);
- jobManager.setBackgroundSynchronization(
- enabled && preferences.getBoolean(R.string.p_background_sync, true));
+ jobManager.updateBackgroundSync(enabled, false);
return enabled;
});
final CheckBoxPreference gtaskPreference = (CheckBoxPreference) findPreference(
@@ -76,7 +75,7 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
}
return false;
} else {
- googleAccountManager.setBackgroundSynchronization(false);
+ jobManager.updateBackgroundSync();
tracker.reportEvent(Tracking.Events.GTASK_DISABLED);
gtasksPreferenceService.stopOngoing();
return true;
@@ -89,9 +88,8 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
}
findPreference(getString(R.string.p_background_sync))
.setOnPreferenceChangeListener((preference, o) -> {
- boolean backgroundSyncEnabled = (Boolean) o;
- jobManager.setBackgroundSynchronization(backgroundSyncEnabled);
- googleAccountManager.setBackgroundSynchronization(backgroundSyncEnabled);
+ boolean enabled = (Boolean) o;
+ jobManager.updateBackgroundSync(false, enabled);
return true;
});
findPreference(getString(R.string.sync_SPr_forget_key))
@@ -101,7 +99,6 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
gtasksPreferenceService.clearLastSyncDate();
gtasksPreferenceService.setUserName(null);
googleTaskDao.deleteAll();
- googleAccountManager.setBackgroundSynchronization(false);
tracker.reportEvent(Tracking.Events.GTASK_LOGOUT);
gtaskPreference.setChecked(false);
})
@@ -120,16 +117,8 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
protected void onResume() {
super.onResume();
- CheckBoxPreference backgroundSync = (CheckBoxPreference) findPreference(
- getString(R.string.p_background_sync));
- if (syncAdapters.isMasterSyncEnabled()) {
- backgroundSync.setSummary(null);
- } else {
- backgroundSync.setSummary(R.string.master_sync_warning);
- }
if (!permissionChecker.canAccessAccounts()) {
((CheckBoxPreference) findPreference(getString(R.string.sync_gtasks))).setChecked(false);
- ((CheckBoxPreference) findPreference(getString(R.string.p_sync_caldav))).setChecked(false);
}
}
@@ -138,9 +127,8 @@ public class SynchronizationPreferences extends InjectingPreferenceActivity {
if (requestCode == REQUEST_LOGIN) {
boolean enabled = resultCode == RESULT_OK;
if (enabled) {
- boolean backgroundSyncEnabled = preferences.getBoolean(R.string.p_background_sync, true);
- googleAccountManager.setBackgroundSynchronization(backgroundSyncEnabled);
tracker.reportEvent(Tracking.Events.GTASK_ENABLED);
+ jobManager.updateBackgroundSync();
}
((CheckBoxPreference) findPreference(getString(R.string.sync_gtasks))).setChecked(enabled);
} else {
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 664c8d8e2..ef961da24 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -166,7 +166,6 @@