diff --git a/api/src/com/todoroo/astrid/sync/SyncResultCallback.java b/api/src/com/todoroo/astrid/sync/SyncResultCallback.java
new file mode 100644
index 000000000..e50d7d5c5
--- /dev/null
+++ b/api/src/com/todoroo/astrid/sync/SyncResultCallback.java
@@ -0,0 +1,25 @@
+package com.todoroo.astrid.sync;
+
+public interface SyncResultCallback {
+ /**
+ * Increment max sync progress
+ * @param incrementBy
+ */
+ public void incrementMax(int incrementBy);
+
+ /**
+ * Increment current sync progress
+ * @param incrementBy
+ */
+ public void incrementProgress(int incrementBy);
+
+ /**
+ * Provider started sync
+ */
+ public void started();
+
+ /**
+ * Provider finished sync
+ */
+ public void finished();
+}
\ No newline at end of file
diff --git a/astrid/src/com/todoroo/astrid/helper/SyncResultCallbackAdapter.java b/api/src/com/todoroo/astrid/sync/SyncResultCallbackAdapter.java
similarity index 86%
rename from astrid/src/com/todoroo/astrid/helper/SyncResultCallbackAdapter.java
rename to api/src/com/todoroo/astrid/sync/SyncResultCallbackAdapter.java
index a7f1ff229..29a95b34c 100644
--- a/astrid/src/com/todoroo/astrid/helper/SyncResultCallbackAdapter.java
+++ b/api/src/com/todoroo/astrid/sync/SyncResultCallbackAdapter.java
@@ -1,6 +1,6 @@
-package com.todoroo.astrid.helper;
+package com.todoroo.astrid.sync;
+
-import com.todoroo.astrid.service.SyncV2Service.SyncResultCallback;
/**
diff --git a/api/src/com/todoroo/astrid/sync/SyncV2BackgroundService.java b/api/src/com/todoroo/astrid/sync/SyncV2BackgroundService.java
new file mode 100644
index 000000000..7c839017d
--- /dev/null
+++ b/api/src/com/todoroo/astrid/sync/SyncV2BackgroundService.java
@@ -0,0 +1,166 @@
+package com.todoroo.astrid.sync;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.todoroo.andlib.service.Autowired;
+import com.todoroo.andlib.service.ContextManager;
+import com.todoroo.andlib.service.DependencyInjectionService;
+import com.todoroo.andlib.service.ExceptionService;
+import com.todoroo.andlib.utility.DateUtilities;
+import com.todoroo.andlib.utility.Preferences;
+import com.todoroo.astrid.api.AstridApiConstants;
+
+/**
+ * Performs synchronization service logic in background service to avoid
+ * ANR (application not responding) messages.
+ *
+ * Starting this service
+ * schedules a repeating alarm which handles
+ * synchronization with your serv
+ *
+ * @author Tim Su
+ *
+ */
+abstract public class SyncV2BackgroundService extends Service {
+
+ /** Minimum time before an auto-sync */
+ private static final long AUTO_SYNC_MIN_OFFSET = 5*60*1000L;
+
+ @Autowired private ExceptionService exceptionService;
+
+ // --- abstract methods
+
+ abstract protected SyncV2Provider getSyncProvider();
+
+ abstract protected SyncProviderUtilities getSyncUtilities();
+
+ // --- implementation
+
+ public SyncV2BackgroundService() {
+ DependencyInjectionService.getInstance().inject(this);
+ }
+
+ private final AtomicBoolean started = new AtomicBoolean(false);
+
+ /** Receive the alarm - start the synchronize service! */
+ @Override
+ public void onStart(Intent intent, int startId) {
+ try {
+ if(intent != null && !started.getAndSet(true)) {
+ startSynchronization(this);
+ }
+ } catch (Exception e) {
+ exceptionService.reportError(getSyncUtilities().getIdentifier() + "-bg-sync", e); //$NON-NLS-1$
+ }
+ }
+
+ /** Start the actual synchronization */
+ private void startSynchronization(final Context context) {
+ if(context == null || context.getResources() == null)
+ return;
+
+ ContextManager.setContext(context);
+
+ if(!getSyncUtilities().isLoggedIn())
+ return;
+
+ getSyncProvider().synchronizeActiveTasks(false, new SyncResultCallbackAdapter() {
+ @Override
+ public void finished() {
+ getSyncUtilities().recordSuccessfulSync();
+ context.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
+ }
+ });
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ public synchronized void stop() {
+ started.set(false);
+ stopSelf();
+ }
+
+ // --- alarm management
+
+ /**
+ * Schedules repeating alarm for auto-synchronization
+ */
+ public void scheduleService() {
+ int syncFrequencySeconds = 0;
+ try {
+ syncFrequencySeconds = Preferences.getIntegerFromString(
+ getSyncUtilities().getSyncIntervalKey(), -1);
+ } catch(ClassCastException e) {
+ Preferences.setStringFromInteger(getSyncUtilities().getSyncIntervalKey(), 0);
+ }
+ Context context = ContextManager.getContext();
+ if(syncFrequencySeconds <= 0) {
+ unscheduleService(context);
+ return;
+ }
+
+ // figure out synchronization frequency
+ long interval = 1000L * syncFrequencySeconds;
+ long offset = computeNextSyncOffset(interval);
+
+ // give a little padding
+ offset = Math.max(offset, AUTO_SYNC_MIN_OFFSET);
+
+ AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ PendingIntent pendingIntent = PendingIntent.getService(context, getSyncUtilities().getSyncIntervalKey(),
+ createAlarmIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
+
+ Log.i("Astrid", "Autosync set for " + offset / 1000 //$NON-NLS-1$ //$NON-NLS-2$
+ + " seconds repeating every " + syncFrequencySeconds); //$NON-NLS-1$
+
+ // cancel all existing
+ am.cancel(pendingIntent);
+
+ // schedule new
+ am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + offset,
+ interval, pendingIntent);
+ }
+
+
+ /**
+ * Removes repeating alarm for auto-synchronization
+ */
+ private void unscheduleService(Context context) {
+ AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
+ PendingIntent pendingIntent = PendingIntent.getService(context, getSyncUtilities().getSyncIntervalKey(),
+ createAlarmIntent(context), PendingIntent.FLAG_UPDATE_CURRENT);
+ am.cancel(pendingIntent);
+ }
+
+ /** Create the alarm intent */
+ private Intent createAlarmIntent(Context context) {
+ Intent intent = new Intent(context, getClass());
+ return intent;
+ }
+
+ // --- utility methods
+
+ private long computeNextSyncOffset(long interval) {
+ // figure out last synchronize time
+ long lastSyncDate = getSyncUtilities().getLastSyncDate();
+
+ // if user never synchronized, give them a full offset period before bg sync
+ if(lastSyncDate != 0)
+ return Math.max(0, lastSyncDate + interval - DateUtilities.now());
+ else
+ return interval;
+ }
+
+
+}
diff --git a/api/src/com/todoroo/astrid/sync/SyncV2Provider.java b/api/src/com/todoroo/astrid/sync/SyncV2Provider.java
new file mode 100644
index 000000000..246d2b776
--- /dev/null
+++ b/api/src/com/todoroo/astrid/sync/SyncV2Provider.java
@@ -0,0 +1,83 @@
+package com.todoroo.astrid.sync;
+
+import java.io.IOException;
+
+import com.todoroo.andlib.service.Autowired;
+import com.todoroo.andlib.service.DependencyInjectionService;
+import com.todoroo.andlib.service.ExceptionService;
+
+
+abstract public class SyncV2Provider {
+
+ public class SyncExceptionHandler {
+ public void handleException(String tag, Exception e) {
+ //TODO: When Crittercism supports it, report error to them
+ getUtilities().setLastError(e.toString());
+
+ // occurs when application was closed
+ if(e instanceof IllegalStateException) {
+ exceptionService.reportError(tag + "-caught", e); //$NON-NLS-1$
+ }
+
+ // occurs when network error
+ else if(e instanceof IOException) {
+ exceptionService.reportError(tag + "-io", e); //$NON-NLS-1$
+ }
+
+ // unhandled error
+ else {
+ exceptionService.reportError(tag + "-unhandled", e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ @Autowired
+ protected ExceptionService exceptionService;
+
+ protected final SyncExceptionHandler handler;
+
+ public SyncV2Provider() {
+ DependencyInjectionService.getInstance().inject(this);
+ handler = new SyncExceptionHandler();
+ }
+
+ /**
+ * @return sync provider name (displayed in sync menu)
+ */
+ abstract public String getName();
+
+ /**
+ * @return true if this provider is logged in
+ */
+ abstract public boolean isActive();
+
+ /**
+ * Synchronize all of user's active tasks
+ * @param manual whether manually triggered
+ * @param callback callback object
+ */
+ abstract public void synchronizeActiveTasks(boolean manual, SyncResultCallback callback);
+
+ /**
+ * Synchronize a single list
+ * @param list object representing list (TaskListActivity-dependent)
+ * @param manual whether was manually triggered
+ * @param callback callback object
+ */
+ abstract public void synchronizeList(Object list, boolean manual, SyncResultCallback callback);
+
+ /**
+ * Sign out of service, deleting all synchronization metadata
+ */
+ abstract public void signOut();
+
+ /**
+ * @return sync utility instance
+ */
+ abstract protected SyncProviderUtilities getUtilities();
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
diff --git a/astrid/plugin-src/com/timsu/astrid/C2DMReceiver.java b/astrid/plugin-src/com/timsu/astrid/C2DMReceiver.java
index cb177186b..eb27171fd 100644
--- a/astrid/plugin-src/com/timsu/astrid/C2DMReceiver.java
+++ b/astrid/plugin-src/com/timsu/astrid/C2DMReceiver.java
@@ -40,11 +40,11 @@ import com.todoroo.astrid.dao.UpdateDao;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.Update;
-import com.todoroo.astrid.helper.SyncResultCallbackAdapter;
import com.todoroo.astrid.reminders.Notifications;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService;
+import com.todoroo.astrid.sync.SyncResultCallbackAdapter;
import com.todoroo.astrid.tags.TagFilterExposer;
import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Flags;
diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmBackgroundService.java b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmBackgroundService.java
index ccfbe7f66..761ac046d 100644
--- a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmBackgroundService.java
+++ b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmBackgroundService.java
@@ -3,11 +3,11 @@ package com.todoroo.astrid.actfm;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
-import com.todoroo.astrid.actfm.sync.ActFmSyncProvider;
+import com.todoroo.astrid.actfm.sync.ActFmSyncV2Provider;
import com.todoroo.astrid.service.StatisticsService;
-import com.todoroo.astrid.sync.SyncBackgroundService;
-import com.todoroo.astrid.sync.SyncProvider;
import com.todoroo.astrid.sync.SyncProviderUtilities;
+import com.todoroo.astrid.sync.SyncV2BackgroundService;
+import com.todoroo.astrid.sync.SyncV2Provider;
/**
* SynchronizationService is the service that performs Astrid's background
@@ -17,7 +17,7 @@ import com.todoroo.astrid.sync.SyncProviderUtilities;
* @author Tim Su
*
*/
-public class ActFmBackgroundService extends SyncBackgroundService {
+public class ActFmBackgroundService extends SyncV2BackgroundService {
@Autowired ActFmPreferenceService actFmPreferenceService;
@@ -26,8 +26,8 @@ public class ActFmBackgroundService extends SyncBackgroundService {
}
@Override
- protected SyncProvider> getSyncProvider() {
- return new ActFmSyncProvider();
+ protected SyncV2Provider getSyncProvider() {
+ return new ActFmSyncV2Provider();
}
@Override
diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmLoginActivity.java b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmLoginActivity.java
index 2c2435add..0dbd9fcbe 100644
--- a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmLoginActivity.java
+++ b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmLoginActivity.java
@@ -77,12 +77,12 @@ import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.activity.Eula;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.gtasks.auth.ModernAuthManager;
-import com.todoroo.astrid.helper.SyncResultCallbackAdapter;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.SyncV2Service;
import com.todoroo.astrid.service.TaskService;
+import com.todoroo.astrid.sync.SyncResultCallbackAdapter;
/**
* This activity allows users to sign in or log in to Astrid.com
diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmPreferences.java b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmPreferences.java
index c44221bfc..27834e7eb 100644
--- a/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmPreferences.java
+++ b/astrid/plugin-src/com/todoroo/astrid/actfm/ActFmPreferences.java
@@ -1,14 +1,18 @@
package com.todoroo.astrid.actfm;
+import android.content.Intent;
import android.content.res.Resources;
import android.preference.Preference;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
+import com.todoroo.andlib.service.ContextManager;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
-import com.todoroo.astrid.actfm.sync.ActFmSyncProvider;
+import com.todoroo.astrid.actfm.sync.ActFmSyncV2Provider;
+import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.sync.SyncProviderPreferences;
import com.todoroo.astrid.sync.SyncProviderUtilities;
+import com.todoroo.astrid.sync.SyncResultCallbackAdapter;
/**
* Displays synchronization preferences and an action panel so users can
@@ -28,13 +32,23 @@ public class ActFmPreferences extends SyncProviderPreferences {
@Override
public void startSync() {
- new ActFmSyncProvider().synchronize(this);
- finish();
+ if (!actFmPreferenceService.isLoggedIn()) {
+ Intent intent = new Intent(this, ActFmLoginActivity.class);
+ startActivityForResult(intent, 0);
+ } else {
+ new ActFmSyncV2Provider().synchronizeActiveTasks(true, new SyncResultCallbackAdapter() {
+ @Override
+ public void finished() {
+ ContextManager.getContext().sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
+ }
+ });
+ finish();
+ }
}
@Override
public void logOut() {
- new ActFmSyncProvider().signOut();
+ new ActFmSyncV2Provider().signOut();
}
@Override
diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java
index b84b836d5..1a41668c7 100644
--- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java
+++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncService.java
@@ -59,6 +59,7 @@ import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService;
+import com.todoroo.astrid.sync.SyncV2Provider.SyncExceptionHandler;
import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.utility.Flags;
@@ -583,7 +584,7 @@ public final class ActFmSyncService {
* Fetch tagData listing asynchronously
*/
public void fetchTagDataDashboard(boolean manual, final Runnable done) {
- invokeFetchList("goal", manual, new ListItemProcessor() {
+ invokeFetchList("goal", manual, null, new ListItemProcessor() {
@Override
protected void mergeAndSave(JSONArray list, HashMap locals) throws JSONException {
TagData remote = new TagData();
@@ -686,8 +687,8 @@ public final class ActFmSyncService {
* @param manual
* @param done
*/
- public void fetchActiveTasks(final boolean manual, Runnable done) {
- invokeFetchList("task", manual, new ListItemProcessor() {
+ public void fetchActiveTasks(final boolean manual, SyncExceptionHandler handler, Runnable done) {
+ invokeFetchList("task", manual, handler, new ListItemProcessor() {
@Override
protected void mergeAndSave(JSONArray list, HashMap locals) throws JSONException {
Task remote = new Task();
@@ -733,7 +734,7 @@ public final class ActFmSyncService {
* @param done
*/
public void fetchTasksForTag(final TagData tagData, final boolean manual, Runnable done) {
- invokeFetchList("task", manual, new ListItemProcessor() {
+ invokeFetchList("task", manual, null, new ListItemProcessor() {
@Override
protected void mergeAndSave(JSONArray list, HashMap locals) throws JSONException {
Task remote = new Task();
@@ -782,7 +783,7 @@ public final class ActFmSyncService {
* @param done
*/
public void fetchUpdatesForTag(final TagData tagData, final boolean manual, Runnable done) {
- invokeFetchList("activity", manual, new UpdateListItemProcessor(), done,
+ invokeFetchList("activity", manual, null, new UpdateListItemProcessor(), done,
"updates:" + tagData.getId(), "tag_id", tagData.getValue(TagData.REMOTE_ID));
}
@@ -793,7 +794,7 @@ public final class ActFmSyncService {
* @param runnable
*/
public void fetchUpdatesForTask(final Task task, boolean manual, Runnable done) {
- invokeFetchList("activity", manual, new UpdateListItemProcessor(), done,
+ invokeFetchList("activity", manual, null, new UpdateListItemProcessor(), done,
"comments:" + task.getId(), "task_id", task.getValue(Task.REMOTE_ID));
}
@@ -803,7 +804,7 @@ public final class ActFmSyncService {
* @param done
*/
public void fetchPersonalUpdates(boolean manual, Runnable done) {
- invokeFetchList("activity", manual, new UpdateListItemProcessor(), done, "personal");
+ invokeFetchList("activity", manual, null, new UpdateListItemProcessor(), done, "personal");
}
private class UpdateListItemProcessor extends ListItemProcessor {
@@ -931,7 +932,7 @@ public final class ActFmSyncService {
}
/** Call sync method */
- private void invokeFetchList(final String model, final boolean manual,
+ private void invokeFetchList(final String model, final boolean manual, final SyncExceptionHandler handler,
final ListItemProcessor> processor, final Runnable done, final String lastSyncKey,
Object... params) {
if(!checkForToken())
@@ -955,7 +956,10 @@ public final class ActFmSyncService {
if(done != null)
done.run();
} catch (IOException e) {
- handleException("io-exception-list-" + model, e);
+ if (handler != null)
+ handler.handleException("io-exception-list-" + model, e);
+ else
+ handleException("io-exception-list-" + model, e);
} catch (JSONException e) {
handleException("json: " + result.toString(), e);
}
diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncV2Provider.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncV2Provider.java
index c4844789b..0aedd5480 100644
--- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncV2Provider.java
+++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/ActFmSyncV2Provider.java
@@ -8,12 +8,11 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.json.JSONException;
+import com.timsu.astrid.C2DMReceiver;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
-import com.todoroo.andlib.service.DependencyInjectionService;
-import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.Preferences;
@@ -22,9 +21,9 @@ import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.StartupService;
-import com.todoroo.astrid.service.SyncV2Service.SyncResultCallback;
-import com.todoroo.astrid.service.SyncV2Service.SyncV2Provider;
import com.todoroo.astrid.service.TaskService;
+import com.todoroo.astrid.sync.SyncResultCallback;
+import com.todoroo.astrid.sync.SyncV2Provider;
import com.todoroo.astrid.tags.TagService;
/**
@@ -37,23 +36,29 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
@Autowired ActFmSyncService actFmSyncService;
- @Autowired ExceptionService exceptionService;
-
@Autowired TaskService taskService;
static {
AstridDependencyInjector.initialize();
}
- public ActFmSyncV2Provider() {
- DependencyInjectionService.getInstance().inject(this);
- }
-
@Override
public String getName() {
return ContextManager.getString(R.string.actfm_APr_header);
}
+ @Override
+ public ActFmPreferenceService getUtilities() {
+ return actFmPreferenceService;
+ }
+
+ @Override
+ public void signOut() {
+ actFmPreferenceService.setToken(null);
+ actFmPreferenceService.clearLastSyncDate();
+ C2DMReceiver.unregister();
+ }
+
@Override
public boolean isActive() {
return actFmPreferenceService.isLoggedIn();
@@ -90,13 +95,15 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
time = actFmSyncService.fetchTags(time);
Preferences.setInt(LAST_TAG_FETCH_TIME, time);
} catch (JSONException e) {
- exceptionService.reportError("actfm-sync", e); //$NON-NLS-1$
+ handler.handleException("actfm-sync", e); //$NON-NLS-1$
} catch (IOException e) {
- exceptionService.reportError("actfm-sync", e); //$NON-NLS-1$
+ handler.handleException("actfm-sync", e); //$NON-NLS-1$
} finally {
callback.incrementProgress(20);
- if(finisher.decrementAndGet() == 0)
+ if(finisher.decrementAndGet() == 0) {
+ actFmPreferenceService.recordSuccessfulSync();
callback.finished();
+ }
}
}
}).start();
@@ -105,14 +112,16 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
/** @return runnable to fetch changes to tags */
private void startTaskFetcher(final boolean manual, final SyncResultCallback callback,
final AtomicInteger finisher) {
- actFmSyncService.fetchActiveTasks(manual, new Runnable() {
+ actFmSyncService.fetchActiveTasks(manual, handler, new Runnable() {
@Override
public void run() {
pushQueued(callback, finisher);
callback.incrementProgress(30);
- if(finisher.decrementAndGet() == 0)
+ if(finisher.decrementAndGet() == 0) {
+ actFmPreferenceService.recordSuccessfulSync();
callback.finished();
+ }
}
});
}
@@ -141,8 +150,10 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
actFmSyncService.pushTaskOnSave(task, task.getMergedValues());
} finally {
callback.incrementProgress(20);
- if(finisher.decrementAndGet() == 0)
+ if(finisher.decrementAndGet() == 0) {
+ actFmPreferenceService.recordSuccessfulSync();
callback.finished();
+ }
}
}
}).start();
diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksBackgroundService.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksBackgroundService.java
index caadda2bb..be65cd9d7 100644
--- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksBackgroundService.java
+++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksBackgroundService.java
@@ -2,19 +2,19 @@ package com.todoroo.astrid.gtasks;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService;
-import com.todoroo.astrid.gtasks.sync.GtasksSyncProvider;
+import com.todoroo.astrid.gtasks.sync.GtasksSyncV2Provider;
import com.todoroo.astrid.service.StatisticsService;
-import com.todoroo.astrid.sync.SyncBackgroundService;
-import com.todoroo.astrid.sync.SyncProvider;
import com.todoroo.astrid.sync.SyncProviderUtilities;
+import com.todoroo.astrid.sync.SyncV2BackgroundService;
+import com.todoroo.astrid.sync.SyncV2Provider;
-public class GtasksBackgroundService extends SyncBackgroundService {
+public class GtasksBackgroundService extends SyncV2BackgroundService {
@Autowired private GtasksPreferenceService gtasksPreferenceService;
@Override
- protected SyncProvider> getSyncProvider() {
- return new GtasksSyncProvider();
+ protected SyncV2Provider getSyncProvider() {
+ return new GtasksSyncV2Provider();
}
@Override
diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksPreferences.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksPreferences.java
index 6d8be9062..456d180c8 100644
--- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksPreferences.java
+++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksPreferences.java
@@ -1,13 +1,18 @@
package com.todoroo.astrid.gtasks;
+import android.content.Intent;
import android.os.Bundle;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
+import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
-import com.todoroo.astrid.gtasks.sync.GtasksSyncProvider;
+import com.todoroo.astrid.api.AstridApiConstants;
+import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity;
+import com.todoroo.astrid.gtasks.sync.GtasksSyncV2Provider;
import com.todoroo.astrid.sync.SyncProviderPreferences;
import com.todoroo.astrid.sync.SyncProviderUtilities;
+import com.todoroo.astrid.sync.SyncResultCallbackAdapter;
/**
* Displays synchronization preferences and an action panel so users can
@@ -37,13 +42,23 @@ public class GtasksPreferences extends SyncProviderPreferences {
@Override
public void startSync() {
- new GtasksSyncProvider().synchronize(this);
- finish();
+ if (!gtasksPreferenceService.isLoggedIn()) {
+ Intent intent = new Intent(this, GtasksLoginActivity.class);
+ startActivityForResult(intent, 0);
+ } else {
+ new GtasksSyncV2Provider().synchronizeActiveTasks(true, new SyncResultCallbackAdapter() {
+ @Override
+ public void finished() {
+ ContextManager.getContext().sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
+ }
+ });
+ finish();
+ }
}
@Override
public void logOut() {
- new GtasksSyncProvider().signOut();
+ new GtasksSyncV2Provider().signOut();
}
@Override
diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/GtasksLoginActivity.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/GtasksLoginActivity.java
index 1637bfcde..c98f877a4 100644
--- a/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/GtasksLoginActivity.java
+++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/auth/GtasksLoginActivity.java
@@ -50,10 +50,10 @@ import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
-import com.todoroo.astrid.helper.SyncResultCallbackAdapter;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.SyncV2Service;
+import com.todoroo.astrid.sync.SyncResultCallbackAdapter;
/**
* This activity allows users to sign in or log in to Google Tasks
diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java
index 010134151..759575600 100644
--- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java
+++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncV2Provider.java
@@ -16,11 +16,11 @@ import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
-import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
+import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.dao.StoreObjectDao;
@@ -41,9 +41,9 @@ import com.todoroo.astrid.gtasks.auth.GtasksTokenValidator;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
-import com.todoroo.astrid.service.SyncV2Service.SyncResultCallback;
-import com.todoroo.astrid.service.SyncV2Service.SyncV2Provider;
import com.todoroo.astrid.service.TaskService;
+import com.todoroo.astrid.sync.SyncResultCallback;
+import com.todoroo.astrid.sync.SyncV2Provider;
import com.todoroo.astrid.utility.Flags;
public class GtasksSyncV2Provider extends SyncV2Provider {
@@ -60,15 +60,24 @@ public class GtasksSyncV2Provider extends SyncV2Provider {
AstridDependencyInjector.initialize();
}
- public GtasksSyncV2Provider() {
- DependencyInjectionService.getInstance().inject(this);
- }
-
@Override
public String getName() {
return ContextManager.getString(R.string.gtasks_GPr_header);
}
+ @Override
+ public GtasksPreferenceService getUtilities() {
+ return gtasksPreferenceService;
+ }
+
+ @Override
+ public void signOut() {
+ gtasksPreferenceService.clearLastSyncDate();
+ gtasksPreferenceService.setToken(null);
+ Preferences.setString(GtasksPreferenceService.PREF_USER_NAME, null);
+ gtasksMetadataService.clearMetadata();
+ }
+
@Override
public boolean isActive() {
return gtasksPreferenceService.isLoggedIn();
@@ -88,7 +97,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider {
try {
gtasksListService.updateLists(invoker.allGtaskLists());
} catch (IOException e) {
- // error updating lists
+ handler.handleException("gtasks-sync=io", e); //$NON-NLS-1$
} finally {
callback.incrementMax(25);
}
@@ -101,8 +110,9 @@ public class GtasksSyncV2Provider extends SyncV2Provider {
new Thread(new Runnable() {
@Override
public void run() {
- synchronizeListHelper(list, invoker, callback);
+ synchronizeListHelper(list, invoker, handler, callback);
if (finisher.decrementAndGet() == 0) {
+ gtasksPreferenceService.recordSuccessfulSync();
callback.finished();
}
}
@@ -126,7 +136,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider {
try {
gtasksSyncService.pushTaskOnSave(task, task.getMergedValues(), invoker, false);
} catch (IOException e) {
- // Eh
+ handler.handleException("gtasks-sync-io", e); //$NON-NLS-1$
} finally {
callback.incrementProgress(10);
}
@@ -156,7 +166,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider {
String authToken = getValidatedAuthToken();
callback.incrementProgress(25);
final GtasksInvoker service = new GtasksInvoker(authToken);
- synchronizeListHelper(gtasksList, service, callback);
+ synchronizeListHelper(gtasksList, service, null, callback);
} finally {
callback.incrementProgress(25);
callback.finished();
@@ -178,7 +188,7 @@ public class GtasksSyncV2Provider extends SyncV2Provider {
}
- private void synchronizeListHelper(StoreObject list, GtasksInvoker invoker, SyncResultCallback callback) {
+ private void synchronizeListHelper(StoreObject list, GtasksInvoker invoker, SyncExceptionHandler handler, SyncResultCallback callback) {
// Do stuff
String listId = list.getValue(GtasksList.REMOTE_ID);
long lastSyncDate;
@@ -208,7 +218,8 @@ public class GtasksSyncV2Provider extends SyncV2Provider {
gtasksTaskListUpdater.correctOrderAndIndentForList(listId);
}
} catch (IOException e) {
- // Stuff
+ if (handler != null)
+ handler.handleException("gtasks-sync-io", e); //$NON-NLS-1$
}
}
diff --git a/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java b/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java
index a2b7cf3cf..971fd596a 100644
--- a/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java
+++ b/astrid/plugin-src/com/todoroo/astrid/notes/EditNoteActivity.java
@@ -59,7 +59,7 @@ import com.todoroo.astrid.helper.ProgressBarSyncResultCallback;
import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
-import com.todoroo.astrid.service.SyncV2Service.SyncResultCallback;
+import com.todoroo.astrid.sync.SyncResultCallback;
import com.todoroo.astrid.timers.TimerActionControlSet.TimerActionListener;
import com.todoroo.astrid.utility.Flags;
diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevBackgroundService.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevBackgroundService.java
index ad3862552..e4773e6fb 100644
--- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevBackgroundService.java
+++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevBackgroundService.java
@@ -6,6 +6,7 @@ import com.todoroo.astrid.sync.SyncBackgroundService;
import com.todoroo.astrid.sync.SyncProvider;
import com.todoroo.astrid.sync.SyncProviderUtilities;
+
/**
* SynchronizationService is the service that performs Astrid's background
* synchronization with online task managers. Starting this service
diff --git a/astrid/src/com/todoroo/astrid/activity/TaskListFragment.java b/astrid/src/com/todoroo/astrid/activity/TaskListFragment.java
index e32b41f21..a3e0eb2c6 100644
--- a/astrid/src/com/todoroo/astrid/activity/TaskListFragment.java
+++ b/astrid/src/com/todoroo/astrid/activity/TaskListFragment.java
@@ -109,11 +109,11 @@ import com.todoroo.astrid.service.StartupService;
import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.SyncV2Service;
-import com.todoroo.astrid.service.SyncV2Service.SyncResultCallback;
-import com.todoroo.astrid.service.SyncV2Service.SyncV2Provider;
import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.service.UpgradeService;
+import com.todoroo.astrid.sync.SyncResultCallback;
+import com.todoroo.astrid.sync.SyncV2Provider;
import com.todoroo.astrid.ui.DateChangedAlerts;
import com.todoroo.astrid.utility.AstridPreferences;
import com.todoroo.astrid.utility.Constants;
diff --git a/astrid/src/com/todoroo/astrid/helper/ProgressBarSyncResultCallback.java b/astrid/src/com/todoroo/astrid/helper/ProgressBarSyncResultCallback.java
index 222d85775..625d59ac3 100644
--- a/astrid/src/com/todoroo/astrid/helper/ProgressBarSyncResultCallback.java
+++ b/astrid/src/com/todoroo/astrid/helper/ProgressBarSyncResultCallback.java
@@ -8,6 +8,7 @@ import android.view.animation.AlphaAnimation;
import android.widget.ProgressBar;
import com.todoroo.andlib.utility.AndroidUtilities;
+import com.todoroo.astrid.sync.SyncResultCallbackAdapter;
public class ProgressBarSyncResultCallback extends SyncResultCallbackAdapter {
diff --git a/astrid/src/com/todoroo/astrid/service/SyncV2Service.java b/astrid/src/com/todoroo/astrid/service/SyncV2Service.java
index a0a975f5e..2b8af7a16 100644
--- a/astrid/src/com/todoroo/astrid/service/SyncV2Service.java
+++ b/astrid/src/com/todoroo/astrid/service/SyncV2Service.java
@@ -6,6 +6,8 @@ import java.util.List;
import com.todoroo.astrid.actfm.sync.ActFmSyncV2Provider;
import com.todoroo.astrid.gtasks.sync.GtasksSyncV2Provider;
+import com.todoroo.astrid.sync.SyncResultCallback;
+import com.todoroo.astrid.sync.SyncV2Provider;
/**
* SyncV2Service is a simplified synchronization interface for supporting
@@ -16,62 +18,6 @@ import com.todoroo.astrid.gtasks.sync.GtasksSyncV2Provider;
*/
public class SyncV2Service {
- public interface SyncResultCallback {
- /**
- * Increment max sync progress
- * @param incrementBy
- */
- public void incrementMax(int incrementBy);
-
- /**
- * Increment current sync progress
- * @param incrementBy
- */
- public void incrementProgress(int incrementBy);
-
- /**
- * Provider started sync
- */
- public void started();
-
- /**
- * Provider finished sync
- */
- public void finished();
- }
-
- abstract public static class SyncV2Provider {
- /**
- * @return sync provider name (displayed in sync menu)
- */
- abstract public String getName();
-
- /**
- * @return true if this provider is logged in
- */
- abstract public boolean isActive();
-
- /**
- * Synchronize all of user's active tasks
- * @param manual whether manually triggered
- * @param callback callback object
- */
- abstract public void synchronizeActiveTasks(boolean manual, SyncResultCallback callback);
-
- /**
- * Synchronize a single list
- * @param list object representing list (TaskListActivity-dependent)
- * @param manual whether was manually triggered
- * @param callback callback object
- */
- abstract public void synchronizeList(Object list, boolean manual, SyncResultCallback callback);
-
- @Override
- public String toString() {
- return getName();
- }
- }
-
/*
* At present, sync provider interactions are handled through code. If
* there is enough interest, the Astrid team could create an interface