Add broadcast receiver to push to gtasks on save

pull/413/head
Alex Baker 8 years ago
parent 27c9e021b8
commit 17672c1e2e

@ -60,6 +60,13 @@
android:name=".scheduling.GtasksBackgroundService"
android:exported="false" />
<receiver android:name=".receivers.GoogleTaskPushReceiver">
<intent-filter>
<action android:name="org.tasks.TASK_SAVED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<!-- Google Analytics -->
<receiver

@ -8,8 +8,6 @@ package com.todoroo.astrid.gtasks.sync;
import android.content.ContentValues;
import android.text.TextUtils;
import com.todoroo.andlib.data.DatabaseDao.ModelUpdateListener;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.dao.MetadataDao;
@ -24,7 +22,6 @@ import com.todoroo.astrid.gtasks.api.GtasksApiUtilities;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.gtasks.api.HttpNotFoundException;
import com.todoroo.astrid.gtasks.api.MoveRequest;
import com.todoroo.astrid.service.TaskService;
import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
@ -58,30 +55,14 @@ public class GtasksSyncService {
this.gtasksPreferenceService = gtasksPreferenceService;
this.gtasksMetadataFactory = gtasksMetadataFactory;
this.gtasksInvoker = gtasksInvoker;
new OperationPushThread(operationQueue).start();
}
private abstract class SyncOnSaveOperation {
abstract public void op(GtasksInvoker invoker) throws IOException;
public interface SyncOnSaveOperation {
void op(GtasksInvoker invoker) throws IOException;
}
private class TaskPushOp extends SyncOnSaveOperation {
protected Task model;
protected long creationDate = DateUtilities.now();
public TaskPushOp(Task model) {
this.model = model;
}
@Override
public void op(GtasksInvoker invoker) throws IOException {
if(DateUtilities.now() - creationDate < 1000) {
AndroidUtilities.sleepDeep(1000 - (DateUtilities.now() - creationDate));
}
pushTaskOnSave(model, model.getMergedValues(), invoker);
}
}
private class MoveOp extends SyncOnSaveOperation {
private class MoveOp implements SyncOnSaveOperation {
protected Metadata metadata;
public MoveOp(Metadata metadata) {
@ -94,7 +75,7 @@ public class GtasksSyncService {
}
}
private class ClearOp extends SyncOnSaveOperation {
private class ClearOp implements SyncOnSaveOperation {
private final String listId;
public ClearOp(String listId) {
@ -107,7 +88,7 @@ public class GtasksSyncService {
}
}
private class NotifyOp extends SyncOnSaveOperation {
private class NotifyOp implements SyncOnSaveOperation {
private final Semaphore sema;
public NotifyOp(Semaphore sema) {
@ -120,30 +101,8 @@ public class GtasksSyncService {
}
}
public void initialize() {
new OperationPushThread(operationQueue).start();
taskDao.addListener(new ModelUpdateListener<Task>() {
@Override
public void onModelUpdated(final Task model) {
if(model.checkAndClearTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) {
return;
}
if (gtasksPreferenceService.isOngoing() && !model.checkTransitory(TaskService.TRANS_REPEAT_COMPLETE)) { //Don't try and sync changes that occur during a normal sync
return;
}
final ContentValues setValues = model.getSetValues();
if(setValues == null || !checkForToken()) {
return;
}
if (!checkValuesForProperties(setValues, TASK_PROPERTIES)) { //None of the properties we sync were updated
return;
}
Task toPush = taskDao.fetch(model.getId(), TASK_PROPERTIES);
operationQueue.offer(new TaskPushOp(toPush));
}
});
public void enqueue(SyncOnSaveOperation operation) {
operationQueue.offer(operation);
}
private class OperationPushThread extends Thread {
@ -183,22 +142,6 @@ public class GtasksSyncService {
}
}
private static final Property<?>[] TASK_PROPERTIES = { Task.ID, Task.TITLE,
Task.NOTES, Task.DUE_DATE, Task.COMPLETION_DATE, Task.DELETION_DATE };
/**
* Checks to see if any of the values changed are among the properties we sync
* @return false if none of the properties we sync were changed, true otherwise
*/
private boolean checkValuesForProperties(ContentValues values, Property<?>[] properties) {
for (Property<?> property : properties) {
if (property != Task.ID && values.containsKey(property.name)) {
return true;
}
}
return false;
}
public void clearCompleted(String listId) {
operationQueue.offer(new ClearOp(listId));
}

@ -2,7 +2,6 @@ package org.tasks;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.GtasksTaskListUpdater;
import com.todoroo.astrid.gtasks.sync.GtasksSyncService;
import org.tasks.billing.InventoryHelper;
import org.tasks.billing.PurchaseHelper;
@ -14,19 +13,16 @@ import javax.inject.Inject;
public class FlavorSetup {
private final Preferences preferences;
private final GtasksSyncService gtasksSyncService;
private final GtasksPreferenceService gtasksPreferenceService;
private final TeslaUnreadReceiver teslaUnreadReceiver;
private final InventoryHelper inventoryHelper;
@Inject
public FlavorSetup(Preferences preferences,
public FlavorSetup(Preferences preferences, GtasksPreferenceService gtasksPreferenceService,
@SuppressWarnings("UnusedParameters") GtasksTaskListUpdater gtasksTaskListUpdater,
@SuppressWarnings("UnusedParameters") PurchaseHelper purchaseHelper,
GtasksSyncService gtasksSyncService, GtasksPreferenceService gtasksPreferenceService,
TeslaUnreadReceiver teslaUnreadReceiver, InventoryHelper inventoryHelper) {
this.preferences = preferences;
this.gtasksSyncService = gtasksSyncService;
this.gtasksPreferenceService = gtasksPreferenceService;
this.teslaUnreadReceiver = teslaUnreadReceiver;
this.inventoryHelper = inventoryHelper;
@ -36,6 +32,5 @@ public class FlavorSetup {
inventoryHelper.initialize();
teslaUnreadReceiver.setEnabled(preferences.getBoolean(R.string.p_tesla_unread_enabled, false));
gtasksPreferenceService.stopOngoing(); // if sync ongoing flag was set, clear it
gtasksSyncService.initialize();
}
}

@ -1,6 +1,7 @@
package org.tasks.injection;
import org.tasks.locale.receiver.FireReceiver;
import org.tasks.receivers.GoogleTaskPushReceiver;
import org.tasks.receivers.TeslaUnreadReceiver;
import dagger.Subcomponent;
@ -10,4 +11,6 @@ public interface BroadcastComponent extends BaseBroadcastComponent {
void inject(TeslaUnreadReceiver teslaUnreadReceiver);
void inject(FireReceiver fireReceiver);
void inject(GoogleTaskPushReceiver forceSyncReceiver);
}

@ -0,0 +1,92 @@
package org.tasks.receivers;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.SyncFlags;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.gtasks.sync.GtasksSyncService;
import com.todoroo.astrid.service.TaskService;
import org.tasks.injection.BroadcastComponent;
import org.tasks.injection.InjectingBroadcastReceiver;
import java.io.IOException;
import javax.inject.Inject;
public class GoogleTaskPushReceiver extends InjectingBroadcastReceiver {
private static final Property<?>[] TASK_PROPERTIES = { Task.ID, Task.TITLE,
Task.NOTES, Task.DUE_DATE, Task.COMPLETION_DATE, Task.DELETION_DATE };
@Inject GtasksPreferenceService gtasksPreferenceService;
@Inject GtasksSyncService gtasksSyncService;
@Inject TaskDao taskDao;
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Task model = intent.getParcelableExtra(AstridApiConstants.EXTRAS_TASK);
if(model.checkAndClearTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) {
return;
}
if (gtasksPreferenceService.isOngoing() && !model.checkTransitory(TaskService.TRANS_REPEAT_COMPLETE)) { //Don't try and sync changes that occur during a normal sync
return;
}
final ContentValues setValues = model.getSetValues();
if(setValues == null || !gtasksPreferenceService.isLoggedIn()) {
return;
}
if (!checkValuesForProperties(setValues, TASK_PROPERTIES)) { //None of the properties we sync were updated
return;
}
Task toPush = taskDao.fetch(model.getId(), TASK_PROPERTIES);
gtasksSyncService.enqueue(new TaskPushOp(toPush));
}
@Override
protected void inject(BroadcastComponent component) {
component.inject(this);
}
private class TaskPushOp implements GtasksSyncService.SyncOnSaveOperation {
protected Task model;
protected long creationDate = DateUtilities.now();
public TaskPushOp(Task model) {
this.model = model;
}
@Override
public void op(GtasksInvoker invoker) throws IOException {
if(DateUtilities.now() - creationDate < 1000) {
AndroidUtilities.sleepDeep(1000 - (DateUtilities.now() - creationDate));
}
gtasksSyncService.pushTaskOnSave(model, model.getMergedValues(), invoker);
}
}
/**
* Checks to see if any of the values changed are among the properties we sync
* @return false if none of the properties we sync were changed, true otherwise
*/
private boolean checkValuesForProperties(ContentValues values, Property<?>[] properties) {
for (Property<?> property : properties) {
if (property != Task.ID && values.containsKey(property.name)) {
return true;
}
}
return false;
}
}

@ -43,8 +43,9 @@ public class AstridApiConstants {
/**
* Extras name for task id
*/
public static final String EXTRAS_TASK_ID = "task";
public static final String EXTRAS_TASK_ID = "task_id";
public static final String EXTRAS_TASK = "task";
/**
* Extras name for old task due date
*/
@ -76,6 +77,8 @@ public class AstridApiConstants {
*/
public static final String BROADCAST_EVENT_TASK_REPEATED = BuildConfig.APPLICATION_ID + ".TASK_REPEATED";
public static final String BROADCAST_EVENT_TASK_SAVED = BuildConfig.APPLICATION_ID + ".TASK_SAVED";
/**
* Action name for broadcast intent notifying that tag was deleted
*/

@ -57,11 +57,17 @@ public class TaskDao {
private GeofenceService geofenceService;
@Inject
public TaskDao(Database database, MetadataDao metadataDao, Broadcaster broadcaster,
public TaskDao(Database database, MetadataDao metadataDao, final Broadcaster broadcaster,
ReminderService reminderService, NotificationManager notificationManager,
Preferences preferences, GeofenceService geofenceService) {
this.geofenceService = geofenceService;
dao = new RemoteModelDao<>(database, Task.class);
dao.addListener(new DatabaseDao.ModelUpdateListener<Task>() {
@Override
public void onModelUpdated(Task model) {
broadcaster.taskUpdated(model);
}
});
this.preferences = preferences;
this.metadataDao = metadataDao;
this.broadcaster = broadcaster;
@ -107,10 +113,6 @@ public class TaskDao {
return dao.deleteWhere(criterion);
}
public void addListener(DatabaseDao.ModelUpdateListener<Task> modelUpdateListener) {
dao.addListener(modelUpdateListener);
}
public List<Task> toList(Query query) {
return dao.toList(query);
}
@ -126,11 +128,6 @@ public class TaskDao {
*/
public static class TaskCriteria {
/** @return tasks by id */
public static Criterion byId(long id) {
return Task.ID.eq(id);
}
/** @return tasks that were not deleted */
public static Criterion notDeleted() {
return Task.DELETION_DATE.eq(0);

@ -4,6 +4,7 @@ import android.content.Context;
import android.content.Intent;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.data.Task;
import org.tasks.injection.ForApplication;
import org.tasks.receivers.CompleteTaskReceiver;
@ -47,6 +48,12 @@ public class Broadcaster {
context.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH));
}
public void taskUpdated(final Task task) {
context.sendBroadcast(new Intent(AstridApiConstants.BROADCAST_EVENT_TASK_SAVED) {{
putExtra(AstridApiConstants.EXTRAS_TASK, task);
}});
}
private void sendOrderedBroadcast(Intent intent) {
sendOrderedBroadcast(intent, null);
}

Loading…
Cancel
Save