Schedule refreshes one day at a time

pull/384/head
Alex Baker 8 years ago
parent 720eb23220
commit 42e5418a3e

@ -479,9 +479,6 @@
<service
android:name=".scheduling.BackupIntentService"
android:exported="false" />
<service
android:name=".scheduling.MidnightRefreshService"
android:exported="false" />
<service
android:name=".scheduling.RefreshSchedulerIntentService"
android:exported="false" />

@ -9,6 +9,7 @@ import android.content.ContentValues;
import android.database.sqlite.SQLiteConstraintException;
import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.data.DatabaseDao;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
@ -70,6 +71,10 @@ public class TaskDao {
return dao.query(query);
}
public void selectActive(Criterion criterion, Callback<Task> callback) {
dao.query(Query.select(Task.PROPERTIES).where(Criterion.and(TaskCriteria.isActive(), criterion)), callback);
}
public Task fetch(long id, Property<?>... properties) {
return dao.fetch(id, properties);
}

@ -225,6 +225,10 @@ public class Task extends RemoteModel {
return getValue(HIDE_UNTIL) > DateUtilities.now();
}
public boolean hasHideUntilDate() {
return getValue(HIDE_UNTIL) > 0;
}
/** Checks whether task is done. Requires DUE_DATE */
public boolean hasDueDate() {
return getValue(DUE_DATE) > 0;

@ -23,7 +23,6 @@ import org.tasks.analytics.Tracker;
import org.tasks.filters.FilterCounter;
import org.tasks.injection.InjectingApplication;
import org.tasks.preferences.Preferences;
import org.tasks.scheduling.RefreshScheduler;
import org.tasks.sync.SyncThrottle;
import javax.inject.Inject;
@ -51,7 +50,6 @@ public class Tasks extends InjectingApplication {
@Inject TagService tagService;
@Inject Broadcaster broadcaster;
@Inject FilterCounter filterCounter;
@Inject RefreshScheduler refreshScheduler;
@Inject SyncThrottle syncThrottle;
@Inject Preferences preferences;
@Inject Tracker tracker;

@ -10,7 +10,6 @@ import dagger.Module;
GeofenceSchedulingIntentService.class,
BackupIntentService.class,
GtasksBackgroundService.class,
MidnightRefreshService.class,
RefreshSchedulerIntentService.class,
ReminderSchedulerIntentService.class,
GeofenceTransitionsIntentService.class,

@ -17,7 +17,6 @@ public class BackgroundScheduler {
}
public void scheduleEverything() {
context.startService(new Intent(context, RefreshSchedulerIntentService.class));
context.startService(new Intent(context, GeofenceSchedulingIntentService.class));
context.startService(new Intent(context, ReminderSchedulerIntentService.class));
scheduleBackupService();
@ -33,7 +32,7 @@ public class BackgroundScheduler {
}
public void scheduleMidnightRefresh() {
context.startService(new Intent(context, MidnightRefreshService.class));
context.startService(new Intent(context, RefreshSchedulerIntentService.class));
}
public void scheduleGtaskSync() {

@ -33,7 +33,7 @@ public class BackupIntentService extends MidnightIntentService {
}
@Override
String getLastRunPreference() {
protected String getLastRunPreference() {
return TasksXmlExporter.PREF_BACKUP_LAST_DATE;
}

@ -10,9 +10,10 @@ import javax.inject.Inject;
import timber.log.Timber;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import static org.tasks.date.DateTimeUtils.newDateTime;
import static org.tasks.time.DateTimeUtils.nextMidnight;
import static org.tasks.time.DateTimeUtils.printTimestamp;
public abstract class MidnightIntentService extends InjectingIntentService {
@ -22,8 +23,11 @@ public abstract class MidnightIntentService extends InjectingIntentService {
@Inject Preferences preferences;
@Inject AlarmManager alarmManager;
private final String name;
public MidnightIntentService(String name) {
super(name);
this.name = name;
}
@Override
@ -36,22 +40,22 @@ public abstract class MidnightIntentService extends InjectingIntentService {
if (nextRun <= now) {
nextRun = nextMidnight(now);
Timber.d("running now [nextRun=%s]", printTimestamp(nextRun));
preferences.setLong(getLastRunPreference(), now);
Timber.d("%s running now [nextRun=%s]", name, printTimestamp(nextRun));
if (!isNullOrEmpty(getLastRunPreference())) {
preferences.setLong(getLastRunPreference(), now);
}
run();
} else {
Timber.d("will run at %s [lastRun=%s]", printTimestamp(nextRun), printTimestamp(lastRun));
Timber.d("%s will run at %s [lastRun=%s]", name, printTimestamp(nextRun), printTimestamp(lastRun));
}
PendingIntent pendingIntent = PendingIntent.getService(this, 0, new Intent(this, this.getClass()), PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.noWakeup(nextRun + PADDING, pendingIntent);
}
private static long nextMidnight(long timestamp) {
return newDateTime(timestamp).startOfDay().plusDays(1).getMillis();
}
abstract void run();
abstract String getLastRunPreference();
protected String getLastRunPreference() {
return null;
}
}

@ -1,24 +0,0 @@
package org.tasks.scheduling;
import org.tasks.Broadcaster;
import javax.inject.Inject;
public class MidnightRefreshService extends MidnightIntentService {
@Inject Broadcaster broadcaster;
public MidnightRefreshService() {
super(MidnightRefreshService.class.getSimpleName());
}
@Override
void run() {
broadcaster.refresh();
}
@Override
String getLastRunPreference() {
return "midnightRefreshDate";
}
}

@ -4,10 +4,8 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
@ -15,24 +13,21 @@ import org.tasks.injection.ForApplication;
import org.tasks.receivers.RefreshReceiver;
import javax.inject.Inject;
import javax.inject.Singleton;
import timber.log.Timber;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static com.todoroo.andlib.utility.DateUtilities.ONE_MINUTE;
import static org.tasks.time.DateTimeUtils.currentTimeMillis;
import static org.tasks.time.DateTimeUtils.nextMidnight;
import static org.tasks.time.DateTimeUtils.printTimestamp;
@Singleton
public class RefreshScheduler {
private final TaskDao taskDao;
private final Context context;
private final AlarmManager alarmManager;
private static final Property<?>[] REFRESH_PROPERTIES = new Property<?>[]{
Task.DUE_DATE,
Task.HIDE_UNTIL
};
@Inject
public RefreshScheduler(TaskDao taskDao, @ForApplication Context context, AlarmManager alarmManager) {
this.taskDao = taskDao;
@ -41,45 +36,39 @@ public class RefreshScheduler {
}
public void scheduleApplicationRefreshes() {
TodorooCursor<Task> cursor = getTasks();
try {
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
Task task = new Task(cursor);
long now = currentTimeMillis();
long midnight = nextMidnight(now);
Criterion criterion = Criterion.or(
Criterion.and(Task.HIDE_UNTIL.gt(now), Task.HIDE_UNTIL.lt(midnight)),
Criterion.and(Task.DUE_DATE.gt(now), Task.DUE_DATE.lt(midnight)));
taskDao.selectActive(criterion, new Callback<Task>() {
@Override
public void apply(Task task) {
scheduleRefresh(task);
}
} finally {
cursor.close();
}
});
}
public void scheduleRefresh(Task task) {
if (task.containsValue(Task.DUE_DATE)) {
if (task.isCompleted()) {
scheduleRefresh(task.getCompletionDate() + ONE_MINUTE);
} else if (task.hasDueDate()) {
scheduleRefresh(task.getDueDate());
}
if (task.containsValue(Task.HIDE_UNTIL)) {
if (task.hasHideUntilDate()) {
scheduleRefresh(task.getHideUntil());
}
if (task.containsValue(Task.COMPLETION_DATE)) {
scheduleRefresh(task.getCompletionDate() + ONE_MINUTE);
}
}
private void scheduleRefresh(Long dueDate) {
if (currentTimeMillis() > dueDate) {
return;
}
dueDate += 1000; // this is ghetto
Intent intent = new Intent(context, RefreshReceiver.class);
intent.setAction(Long.toString(dueDate));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, FLAG_UPDATE_CURRENT);
alarmManager.noWakeup(dueDate, pendingIntent);
}
private TodorooCursor<Task> getTasks() {
private void scheduleRefresh(Long refreshTime) {
long now = currentTimeMillis();
return taskDao.query(Query.select(REFRESH_PROPERTIES).where(Criterion.and(
TaskDao.TaskCriteria.isActive(),
Criterion.or(Task.HIDE_UNTIL.gt(now), Task.DUE_DATE.gt(now)))));
if (now < refreshTime && refreshTime < nextMidnight(now)) {
refreshTime += 1000; // this is ghetto
Timber.d("Scheduling refresh at %s", printTimestamp(refreshTime));
Intent intent = new Intent(context, RefreshReceiver.class);
intent.setAction(Long.toString(refreshTime));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, FLAG_UPDATE_CURRENT);
alarmManager.noWakeup(refreshTime, pendingIntent);
}
}
}

@ -1,15 +1,12 @@
package org.tasks.scheduling;
import android.content.Intent;
import org.tasks.injection.InjectingIntentService;
import org.tasks.Broadcaster;
import javax.inject.Inject;
import timber.log.Timber;
public class RefreshSchedulerIntentService extends InjectingIntentService {
public class RefreshSchedulerIntentService extends MidnightIntentService {
@Inject Broadcaster broadcaster;
@Inject RefreshScheduler refreshScheduler;
public RefreshSchedulerIntentService() {
@ -17,11 +14,8 @@ public class RefreshSchedulerIntentService extends InjectingIntentService {
}
@Override
protected void onHandleIntent(Intent intent) {
super.onHandleIntent(intent);
Timber.d("onHandleIntent(%s)", intent);
void run() {
refreshScheduler.scheduleApplicationRefreshes();
broadcaster.refresh();
}
}

@ -1,7 +1,11 @@
package org.tasks.time;
import org.tasks.BuildConfig;
import java.util.Date;
import static org.tasks.date.DateTimeUtils.newDateTime;
public class DateTimeUtils {
private static final SystemMillisProvider SYSTEM_MILLIS_PROVIDER = new SystemMillisProvider();
@ -19,7 +23,13 @@ public class DateTimeUtils {
MILLIS_PROVIDER = SYSTEM_MILLIS_PROVIDER;
}
public static long nextMidnight(long timestamp) {
return newDateTime(timestamp).startOfDay().plusDays(1).getMillis();
}
public static String printTimestamp(long timestamp) {
return new Date(timestamp).toString();
return BuildConfig.DEBUG
? new Date(timestamp).toString()
: Long.toString(timestamp);
}
}

Loading…
Cancel
Save