From 328877a2d656cd7c5bb96e8e34104e68cd3081fe Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Thu, 17 Jul 2014 09:21:34 -0500 Subject: [PATCH] Hide alarm cursors --- .../astrid/alarms/AlarmControlSet.java | 14 +-- .../todoroo/astrid/alarms/AlarmService.java | 118 ++++++------------ .../alarms/AlarmTaskRepeatListener.java | 31 ++--- .../com/todoroo/astrid/dao/MetadataDao.java | 7 +- 4 files changed, 64 insertions(+), 106 deletions(-) diff --git a/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmControlSet.java b/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmControlSet.java index a70930bf2..b1cbaa64c 100644 --- a/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmControlSet.java +++ b/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmControlSet.java @@ -13,7 +13,7 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; -import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.data.Callback; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; @@ -53,14 +53,12 @@ public final class AlarmControlSet extends TaskEditControlSet { @Override protected void readFromTaskOnInitialize() { alertsContainer.removeAllViews(); - TodorooCursor cursor = alarmService.getAlarms(model.getId()); - try { - for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { - addAlarm(newDate(cursor.get(AlarmFields.TIME))); + alarmService.getAlarms(model.getId(), new Callback() { + @Override + public void apply(Metadata entry) { + addAlarm(newDate(entry.getValue(AlarmFields.TIME))); } - } finally { - cursor.close(); - } + }); } @Override diff --git a/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmService.java b/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmService.java index 00d68a46a..477853ebe 100644 --- a/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmService.java +++ b/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmService.java @@ -11,7 +11,7 @@ import android.content.ContentValues; import android.content.Context; import android.content.Intent; -import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.data.Callback; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Join; import com.todoroo.andlib.sql.Order; @@ -26,14 +26,13 @@ import com.todoroo.astrid.reminders.Notifications; import com.todoroo.astrid.reminders.ReminderService; import com.todoroo.astrid.service.SynchronizeMetadataCallback; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.tasks.injection.ForApplication; import java.util.ArrayList; import java.util.HashSet; -import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -47,12 +46,16 @@ import javax.inject.Singleton; @Singleton public class AlarmService { - private static final Logger log = LoggerFactory.getLogger(AlarmService.class); - - // --- data retrieval + private static final long NO_ALARM = Long.MAX_VALUE; - private MetadataDao metadataDao; + private final MetadataDao metadataDao; private final Context context; + private final Callback scheduleAlarm = new Callback() { + @Override + public void apply(Metadata alarm) { + scheduleAlarm(alarm); + } + }; @Inject public AlarmService(MetadataDao metadataDao, @ForApplication Context context) { @@ -60,11 +63,8 @@ public class AlarmService { this.context = context; } - /** - * Return alarms for the given task. PLEASE CLOSE THE CURSOR! - */ - public TodorooCursor getAlarms(long taskId) { - return metadataDao.query(Query.select( + public void getAlarms(long taskId, Callback callback) { + metadataDao.query(callback, Query.select( Metadata.PROPERTIES).where(MetadataCriteria.byTaskAndwithKey( taskId, AlarmFields.METADATA_KEY)).orderBy(Order.asc(AlarmFields.TIME))); } @@ -73,8 +73,8 @@ public class AlarmService { * Save the given array of alarms into the database * @return true if data was changed */ - public boolean synchronizeAlarms(final long taskId, LinkedHashSet alarms) { - ArrayList metadata = new ArrayList<>(); + public boolean synchronizeAlarms(final long taskId, Set alarms) { + List metadata = new ArrayList<>(); for(Long alarm : alarms) { Metadata item = new Metadata(); item.setKey(AlarmFields.METADATA_KEY); @@ -85,7 +85,7 @@ public class AlarmService { final AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); - boolean changed = synchronizeMetadata(taskId, metadata, Metadata.KEY.eq(AlarmFields.METADATA_KEY), new SynchronizeMetadataCallback() { + boolean changed = synchronizeMetadata(taskId, metadata, new SynchronizeMetadataCallback() { @Override public void beforeDeleteMetadata(Metadata m) { // Cancel the alarm before the metadata is deleted @@ -102,22 +102,14 @@ public class AlarmService { // --- alarm scheduling - /** - * Gets a listing of all alarms that are active - * @return todoroo cursor. PLEASE CLOSE THIS CURSOR! - */ - private TodorooCursor getActiveAlarms() { - return metadataDao.query(Query.select(Metadata.ID, Metadata.TASK, AlarmFields.TIME). + private void getActiveAlarms(Callback callback) { + metadataDao.query(callback, Query.select(Metadata.ID, Metadata.TASK, AlarmFields.TIME). join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))). where(Criterion.and(TaskCriteria.isActive(), MetadataCriteria.withKey(AlarmFields.METADATA_KEY)))); } - /** - * Gets a listing of alarms by task - * @return todoroo cursor. PLEASE CLOSE THIS CURSOR! - */ - private TodorooCursor getActiveAlarmsForTask(long taskId) { - return metadataDao.query(Query.select(Metadata.ID, Metadata.TASK, AlarmFields.TIME). + private void getActiveAlarmsForTask(long taskId, Callback callback) { + metadataDao.query(callback, Query.select(Metadata.ID, Metadata.TASK, AlarmFields.TIME). join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))). where(Criterion.and(TaskCriteria.isActive(), MetadataCriteria.byTaskAndwithKey(taskId, AlarmFields.METADATA_KEY)))); @@ -127,37 +119,14 @@ public class AlarmService { * Schedules all alarms */ public void scheduleAllAlarms() { - TodorooCursor cursor = getActiveAlarms(); - try { - for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { - Metadata alarm = new Metadata(cursor); - scheduleAlarm(alarm); - } - } catch (Exception e) { - // suppress - log.error(e.getMessage(), e); - } finally { - cursor.close(); - } + getActiveAlarms(scheduleAlarm); } - private static final long NO_ALARM = Long.MAX_VALUE; - /** * Schedules alarms for a single task */ - public void scheduleAlarms(long taskId) { - TodorooCursor cursor = getActiveAlarmsForTask(taskId); - try { - for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { - Metadata alarm = new Metadata(cursor); - scheduleAlarm(alarm); - } - } catch (Exception e) { - log.error(e.getMessage(), e); - } finally { - cursor.close(); - } + private void scheduleAlarms(long taskId) { + getActiveAlarmsForTask(taskId, scheduleAlarm); } private PendingIntent pendingIntentForAlarm(Metadata alarm, long taskId) { @@ -191,10 +160,9 @@ public class AlarmService { } } - private boolean synchronizeMetadata(long taskId, ArrayList metadata, - Criterion metadataCriterion, SynchronizeMetadataCallback callback) { - boolean dirty = false; - HashSet newMetadataValues = new HashSet<>(); + private boolean synchronizeMetadata(long taskId, List metadata, final SynchronizeMetadataCallback callback) { + final boolean[] dirty = new boolean[1]; + final Set newMetadataValues = new HashSet<>(); for(Metadata metadatum : metadata) { metadatum.setTask(taskId); metadatum.clearValue(Metadata.CREATION_DATE); @@ -210,12 +178,9 @@ public class AlarmService { newMetadataValues.add(values); } - TodorooCursor cursor = metadataDao.query(Query.select(Metadata.PROPERTIES).where(Criterion.and(MetadataCriteria.byTask(taskId), - metadataCriterion))); - try { - // try to find matches within our metadata list - for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { - Metadata item = new Metadata(cursor); + metadataDao.byTaskAndKey(taskId, AlarmFields.METADATA_KEY, new Callback() { + @Override + public void apply(Metadata item) { long id = item.getId(); // clear item id when matching with incoming values @@ -225,20 +190,17 @@ public class AlarmService { if(newMetadataValues.contains(itemMergedValues)) { newMetadataValues.remove(itemMergedValues); - continue; - } - - // not matched. cut it - item.setId(id); - if (callback != null) { - callback.beforeDeleteMetadata(item); + } else { + // not matched. cut it + item.setId(id); + if (callback != null) { + callback.beforeDeleteMetadata(item); + } + metadataDao.delete(id); + dirty[0] = true; } - metadataDao.delete(id); - dirty = true; } - } finally { - cursor.close(); - } + }); // everything that remains shall be written for(ContentValues values : newMetadataValues) { @@ -246,9 +208,9 @@ public class AlarmService { item.setCreationDate(DateUtilities.now()); item.mergeWith(values); metadataDao.persist(item); - dirty = true; + dirty[0] = true; } - return dirty; + return dirty[0]; } } diff --git a/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmTaskRepeatListener.java b/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmTaskRepeatListener.java index b53e0f4e3..6c057092c 100644 --- a/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmTaskRepeatListener.java +++ b/astrid/src/main/java/com/todoroo/astrid/alarms/AlarmTaskRepeatListener.java @@ -8,7 +8,7 @@ package com.todoroo.astrid.alarms; import android.content.Context; import android.content.Intent; -import com.todoroo.andlib.data.TodorooCursor; +import com.todoroo.andlib.data.Callback; import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.api.AstridApiConstants; @@ -17,6 +17,7 @@ import com.todoroo.astrid.data.Metadata; import org.tasks.injection.InjectingBroadcastReceiver; import java.util.LinkedHashSet; +import java.util.Set; import javax.inject.Inject; @@ -34,31 +35,23 @@ public class AlarmTaskRepeatListener extends InjectingBroadcastReceiver { return; } - long oldDueDate = intent.getLongExtra(AstridApiConstants.EXTRAS_OLD_DUE_DATE, 0); - if(oldDueDate == 0) { - oldDueDate = DateUtilities.now(); - } - long newDueDate = intent.getLongExtra(AstridApiConstants.EXTRAS_NEW_DUE_DATE, -1); + long oldDueDateExtra = intent.getLongExtra(AstridApiConstants.EXTRAS_OLD_DUE_DATE, 0); + final long oldDueDate = oldDueDateExtra == 0 ? DateUtilities.now() : oldDueDateExtra; + final long newDueDate = intent.getLongExtra(AstridApiConstants.EXTRAS_NEW_DUE_DATE, -1); + if(newDueDate <= 0 || newDueDate <= oldDueDate) { return; } - TodorooCursor cursor = alarmService.getAlarms(taskId); - try { - if(cursor.getCount() == 0) { - return; - } - - LinkedHashSet alarms = new LinkedHashSet<>(cursor.getCount()); - for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { - Metadata metadata = new Metadata(cursor); + final Set alarms = new LinkedHashSet<>(); + alarmService.getAlarms(taskId, new Callback() { + @Override + public void apply(Metadata metadata) { alarms.add(metadata.getValue(AlarmFields.TIME) + (newDueDate - oldDueDate)); } + }); + if (!alarms.isEmpty()) { alarmService.synchronizeAlarms(taskId, alarms); - - } finally { - cursor.close(); } } - } diff --git a/astrid/src/main/java/com/todoroo/astrid/dao/MetadataDao.java b/astrid/src/main/java/com/todoroo/astrid/dao/MetadataDao.java index ee34f2cb5..c5d791f6f 100644 --- a/astrid/src/main/java/com/todoroo/astrid/dao/MetadataDao.java +++ b/astrid/src/main/java/com/todoroo/astrid/dao/MetadataDao.java @@ -5,6 +5,7 @@ */ package com.todoroo.astrid.dao; +import com.todoroo.andlib.data.Callback; import com.todoroo.andlib.data.DatabaseDao; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Join; @@ -52,7 +53,6 @@ public class MetadataDao extends DatabaseDao { public static Criterion byTaskAndwithKey(long taskId, String key) { return Criterion.and(withKey(key), byTask(taskId)); } - } @Override @@ -74,5 +74,10 @@ public class MetadataDao extends DatabaseDao { deleteWhere(Metadata.ID.in(Query.select(Metadata.ID).from(Metadata.TABLE).join(Join.left(Task.TABLE, Metadata.TASK.eq(Task.ID))).where(Task.TITLE.isNull()))); } + + public void byTaskAndKey(long taskId, String key, Callback callback) { + query(callback, Query.select(Metadata.PROPERTIES).where( + Criterion.and(Metadata.TASK.eq(taskId), Metadata.KEY.eq(key)))); + } }