Don't touch the cursor in the background

This prevents accessing a potentially closed cursor when doing batch
operations that will inevitable cause the the list to be reloaded (and
cursor to be invalidated) as the first of the messages are
touched

Bug: 5051730
Change-Id: I90328ee02eafe6ad238d8c57e88a3d96259f6547
This commit is contained in:
Ben Komalo 2011-07-21 19:37:14 -07:00
parent af5826cc7a
commit 5fb6c5d4de

View File

@ -69,7 +69,9 @@ import com.android.emailcommon.provider.Mailbox;
import com.android.emailcommon.utility.EmailAsyncTask; import com.android.emailcommon.utility.EmailAsyncTask;
import com.android.emailcommon.utility.Utility; import com.android.emailcommon.utility.Utility;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
import java.util.HashMap;
import java.util.Set; import java.util.Set;
/** /**
@ -860,16 +862,13 @@ public class MessageListFragment extends ListFragment
toggleMultiple(selectedSet, new MultiToggleHelper() { toggleMultiple(selectedSet, new MultiToggleHelper() {
@Override @Override
public boolean getField(long messageId, Cursor c) { public boolean getField(Cursor c) {
return c.getInt(MessagesAdapter.COLUMN_READ) == 0; return c.getInt(MessagesAdapter.COLUMN_READ) == 0;
} }
@Override @Override
public void setField(long messageId, Cursor c, boolean newValue) { public void setField(long messageId, boolean newValue) {
boolean oldValue = getField(messageId, c); mController.setMessageReadSync(messageId, !newValue);
if (oldValue != newValue) {
mController.setMessageReadSync(messageId, !newValue);
}
} }
}); });
} }
@ -883,16 +882,13 @@ public class MessageListFragment extends ListFragment
toggleMultiple(selectedSet, new MultiToggleHelper() { toggleMultiple(selectedSet, new MultiToggleHelper() {
@Override @Override
public boolean getField(long messageId, Cursor c) { public boolean getField(Cursor c) {
return c.getInt(MessagesAdapter.COLUMN_FAVORITE) != 0; return c.getInt(MessagesAdapter.COLUMN_FAVORITE) != 0;
} }
@Override @Override
public void setField(long messageId, Cursor c, boolean newValue) { public void setField(long messageId, boolean newValue) {
boolean oldValue = getField(messageId, c); mController.setMessageFavoriteSync(messageId, newValue);
if (oldValue != newValue) {
mController.setMessageFavoriteSync(messageId, newValue);
}
} }
}); });
} }
@ -910,19 +906,17 @@ public class MessageListFragment extends ListFragment
/** /**
* Return true if the field of interest is "set". If one or more are false, then our * Return true if the field of interest is "set". If one or more are false, then our
* bulk action will be to "set". If all are set, our bulk action will be to "clear". * bulk action will be to "set". If all are set, our bulk action will be to "clear".
* @param messageId the message id of the current message
* @param c the cursor, positioned to the item of interest * @param c the cursor, positioned to the item of interest
* @return true if the field at this row is "set" * @return true if the field at this row is "set"
*/ */
public boolean getField(long messageId, Cursor c); public boolean getField(Cursor c);
/** /**
* Set or clear the field of interest; setField is called asynchronously via EmailAsyncTask * Set or clear the field of interest; setField is called asynchronously via EmailAsyncTask
* @param messageId the message id of the current message * @param messageId the message id of the current message
* @param c the cursor, positioned to the item of interest
* @param newValue the new value to be set at this row * @param newValue the new value to be set at this row
*/ */
public void setField(long messageId, Cursor c, boolean newValue); public void setField(long messageId, boolean newValue);
} }
/** /**
@ -935,33 +929,35 @@ public class MessageListFragment extends ListFragment
*/ */
private void toggleMultiple(final Set<Long> selectedSet, final MultiToggleHelper helper) { private void toggleMultiple(final Set<Long> selectedSet, final MultiToggleHelper helper) {
final Cursor c = mListAdapter.getCursor(); final Cursor c = mListAdapter.getCursor();
boolean anyWereFound = false; if (c == null || c.isClosed()) {
return;
}
final HashMap<Long, Boolean> setValues = Maps.newHashMap();
boolean allWereSet = true; boolean allWereSet = true;
c.moveToPosition(-1); c.moveToPosition(-1);
while (c.moveToNext()) { while (c.moveToNext()) {
long id = c.getInt(MessagesAdapter.COLUMN_ID); long id = c.getInt(MessagesAdapter.COLUMN_ID);
if (selectedSet.contains(Long.valueOf(id))) { if (selectedSet.contains(id)) {
anyWereFound = true; boolean value = helper.getField(c);
if (!helper.getField(id, c)) { setValues.put(id, value);
allWereSet = false; allWereSet = allWereSet && value;
break;
}
} }
} }
if (anyWereFound) { if (!setValues.isEmpty()) {
final boolean newValue = !allWereSet; final boolean newValue = !allWereSet;
c.moveToPosition(-1); c.moveToPosition(-1);
// TODO: we should probably put up a dialog or some other progress indicator for this.
EmailAsyncTask.runAsyncParallel(new Runnable() { EmailAsyncTask.runAsyncParallel(new Runnable() {
@Override @Override
public void run() { public void run() {
while (c.moveToNext()) { for (long id : setValues.keySet()) {
long id = c.getInt(MessagesAdapter.COLUMN_ID); if (setValues.get(id) != newValue) {
if (selectedSet.contains(Long.valueOf(id))) { helper.setField(id, newValue);
helper.setField(id, c, newValue); }
} }
}
}}); }});
} }
} }
@ -969,12 +965,12 @@ public class MessageListFragment extends ListFragment
/** /**
* Test selected messages for showing appropriate labels * Test selected messages for showing appropriate labels
* @param selectedSet * @param selectedSet
* @param column_id * @param columnId
* @param defaultflag * @param defaultflag
* @return true when the specified flagged message is selected * @return true when the specified flagged message is selected
*/ */
private boolean testMultiple(Set<Long> selectedSet, int column_id, boolean defaultflag) { private boolean testMultiple(Set<Long> selectedSet, int columnId, boolean defaultflag) {
Cursor c = mListAdapter.getCursor(); final Cursor c = mListAdapter.getCursor();
if (c == null || c.isClosed()) { if (c == null || c.isClosed()) {
return false; return false;
} }
@ -982,7 +978,7 @@ public class MessageListFragment extends ListFragment
while (c.moveToNext()) { while (c.moveToNext()) {
long id = c.getInt(MessagesAdapter.COLUMN_ID); long id = c.getInt(MessagesAdapter.COLUMN_ID);
if (selectedSet.contains(Long.valueOf(id))) { if (selectedSet.contains(Long.valueOf(id))) {
if (c.getInt(column_id) == (defaultflag ? 1 : 0)) { if (c.getInt(columnId) == (defaultflag ? 1 : 0)) {
return true; return true;
} }
} }