1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-15 22:15:15 -05:00

Synchronize iterator accesses to mHandler.messages to avoid ConcurrentModificationException in MessageList. Original analysis and patch was provided by fiouzy.

Fixes issue 1598
This commit is contained in:
cketti 2010-07-11 22:01:11 +00:00
parent 7b63c8091c
commit e3cb9f4603

View File

@ -200,7 +200,11 @@ public class MessageList
if (mFolderName == null || (message.folder != null && message.folder.name.equals(mFolderName))) if (mFolderName == null || (message.folder != null && message.folder.name.equals(mFolderName)))
{ {
int index = Collections.binarySearch(mAdapter.messages, message); int index;
synchronized (mAdapter.messages)
{
index = Collections.binarySearch(mAdapter.messages, message);
}
if (index < 0) if (index < 0)
{ {
@ -238,10 +242,13 @@ public class MessageList
if (mQueryString != null) if (mQueryString != null)
{ {
int unreadCount = 0; int unreadCount = 0;
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
unreadCount += holder.read ? 0 : 1; unreadCount += holder.read ? 0 : 1;
} }
}
mUnreadMessageCount = unreadCount; mUnreadMessageCount = unreadCount;
refreshTitleOnThread(); refreshTitleOnThread();
} }
@ -843,11 +850,14 @@ public class MessageList
// Need to get the list before the sort starts // Need to get the list before the sort starts
ArrayList<MessageReference> messageRefs = new ArrayList<MessageReference>(); ArrayList<MessageReference> messageRefs = new ArrayList<MessageReference>();
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
MessageReference ref = holder.message.makeMessageReference(); MessageReference ref = holder.message.makeMessageReference();
messageRefs.add(ref); messageRefs.add(ref);
} }
}
MessageReference ref = message.message.makeMessageReference(); MessageReference ref = message.message.makeMessageReference();
Log.i(K9.LOG_TAG, "MessageList sending message " + ref); Log.i(K9.LOG_TAG, "MessageList sending message " + ref);
@ -1216,11 +1226,13 @@ public class MessageList
mController.markAllMessagesRead(mAccount, mCurrentFolder.name); mController.markAllMessagesRead(mAccount, mCurrentFolder.name);
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
holder.read = true; holder.read = true;
} }
}
mHandler.sortMessages(); mHandler.sortMessages();
@ -2086,6 +2098,8 @@ public class MessageList
// XXX TODO - make this not use a for loop // XXX TODO - make this not use a for loop
public MessageInfoHolder getMessage(MessageReference messageReference) public MessageInfoHolder getMessage(MessageReference messageReference)
{
synchronized (mAdapter.messages)
{ {
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
@ -2097,12 +2111,12 @@ public class MessageList
* Please remove this comment once the cause was found and the * Please remove this comment once the cause was found and the
* bug(?) fixed. * bug(?) fixed.
*/ */
if ((holder != null) && if ((holder != null) && holder.message.equalsReference(messageReference))
holder.message.equalsReference(messageReference))
{ {
return holder; return holder;
} }
} }
}
return null; return null;
} }
@ -2165,12 +2179,15 @@ public class MessageList
public Object getItem(int position) public Object getItem(int position)
{ {
try try
{
synchronized (mAdapter.messages)
{ {
if (position < mAdapter.messages.size()) if (position < mAdapter.messages.size())
{ {
return mAdapter.messages.get(position); return mAdapter.messages.get(position);
} }
} }
}
catch (Exception e) catch (Exception e)
{ {
Log.e(K9.LOG_TAG, "getItem(" + position + "), but folder.messages.size() = " + mAdapter.messages.size(), e); Log.e(K9.LOG_TAG, "getItem(" + position + "), but folder.messages.size() = " + mAdapter.messages.size(), e);
@ -2844,6 +2861,8 @@ public class MessageList
{ {
boolean newState = false; boolean newState = false;
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -2864,10 +2883,13 @@ public class MessageList
} }
} }
} }
}
return newState; return newState;
} }
private boolean anySelected() private boolean anySelected()
{
synchronized (mAdapter.messages)
{ {
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
@ -2876,6 +2898,7 @@ public class MessageList
return true; return true;
} }
} }
}
return false; return false;
} }
@ -2899,6 +2922,8 @@ public class MessageList
{ {
newState = computeBatchDirection(false); newState = computeBatchDirection(false);
} }
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
@ -2919,6 +2944,7 @@ public class MessageList
messageList.add(holder.message); messageList.add(holder.message);
} }
} }
}
mAdapter.removeMessages(removeHolderList); mAdapter.removeMessages(removeHolderList);
if (!messageList.isEmpty()) if (!messageList.isEmpty())
@ -2945,11 +2971,14 @@ public class MessageList
private void setAllSelected(boolean isSelected) private void setAllSelected(boolean isSelected)
{ {
mSelectedCount = 0; mSelectedCount = 0;
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
holder.selected = isSelected; holder.selected = isSelected;
mSelectedCount += (isSelected ? 1 : 0); mSelectedCount += (isSelected ? 1 : 0);
} }
}
mAdapter.notifyDataSetChanged(); mAdapter.notifyDataSetChanged();
toggleBatchButtons(); toggleBatchButtons();
} }
@ -2971,6 +3000,8 @@ public class MessageList
private void flagSelected(Flag flag, boolean newState) private void flagSelected(Flag flag, boolean newState)
{ {
List<Message> messageList = new ArrayList<Message>(); List<Message> messageList = new ArrayList<Message>();
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -2986,6 +3017,7 @@ public class MessageList
} }
} }
} }
}
mController.setFlag(messageList.toArray(new Message[0]), flag, newState); mController.setFlag(messageList.toArray(new Message[0]), flag, newState);
mHandler.sortMessages(); mHandler.sortMessages();
} }
@ -2994,6 +3026,8 @@ public class MessageList
{ {
List<Message> messageList = new ArrayList<Message>(); List<Message> messageList = new ArrayList<Message>();
List<MessageInfoHolder> removeHolderList = new ArrayList<MessageInfoHolder>(); List<MessageInfoHolder> removeHolderList = new ArrayList<MessageInfoHolder>();
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -3002,6 +3036,7 @@ public class MessageList
messageList.add(holder.message); messageList.add(holder.message);
} }
} }
}
mAdapter.removeMessages(removeHolderList); mAdapter.removeMessages(removeHolderList);
mController.deleteMessages(messageList.toArray(new Message[0]), null); mController.deleteMessages(messageList.toArray(new Message[0]), null);
@ -3015,6 +3050,8 @@ public class MessageList
{ {
return; return;
} }
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -3022,12 +3059,14 @@ public class MessageList
Message message = holder.message; Message message = holder.message;
if (mController.isMoveCapable(message) == false) if (mController.isMoveCapable(message) == false)
{ {
Toast toast = Toast.makeText(this, R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG); Toast toast = Toast.makeText(this,
R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
toast.show(); toast.show();
return; return;
} }
} }
} }
}
final Folder folder = mCurrentFolder.folder; final Folder folder = mCurrentFolder.folder;
final Intent intent = new Intent(this, ChooseFolder.class); final Intent intent = new Intent(this, ChooseFolder.class);
@ -3046,6 +3085,8 @@ public class MessageList
List<Message> messageList = new ArrayList<Message>(); List<Message> messageList = new ArrayList<Message>();
List<MessageInfoHolder> removeHolderList = new ArrayList<MessageInfoHolder>(); List<MessageInfoHolder> removeHolderList = new ArrayList<MessageInfoHolder>();
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -3053,7 +3094,8 @@ public class MessageList
Message message = holder.message; Message message = holder.message;
if (mController.isMoveCapable(message) == false) if (mController.isMoveCapable(message) == false)
{ {
Toast toast = Toast.makeText(this, R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG); Toast toast = Toast.makeText(this,
R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
toast.show(); toast.show();
return; return;
} }
@ -3061,6 +3103,7 @@ public class MessageList
removeHolderList.add(holder); removeHolderList.add(holder);
} }
} }
}
mAdapter.removeMessages(removeHolderList); mAdapter.removeMessages(removeHolderList);
mController.moveMessages(mAccount, mCurrentFolder.name, messageList.toArray(new Message[0]), folderName, null); mController.moveMessages(mAccount, mCurrentFolder.name, messageList.toArray(new Message[0]), folderName, null);
@ -3074,7 +3117,9 @@ public class MessageList
{ {
return; return;
} }
Account account = null;
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -3088,6 +3133,7 @@ public class MessageList
} }
} }
} }
}
String folderName = mAccount.getArchiveFolderName(); String folderName = mAccount.getArchiveFolderName();
if (K9.FOLDER_NONE.equalsIgnoreCase(folderName)) if (K9.FOLDER_NONE.equalsIgnoreCase(folderName))
@ -3103,7 +3149,9 @@ public class MessageList
{ {
return; return;
} }
Account account = null;
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -3117,6 +3165,7 @@ public class MessageList
} }
} }
} }
}
String folderName = mAccount.getSpamFolderName(); String folderName = mAccount.getSpamFolderName();
if (K9.FOLDER_NONE.equalsIgnoreCase(folderName)) if (K9.FOLDER_NONE.equalsIgnoreCase(folderName))
@ -3132,6 +3181,8 @@ public class MessageList
{ {
return; return;
} }
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -3139,12 +3190,14 @@ public class MessageList
Message message = holder.message; Message message = holder.message;
if (mController.isCopyCapable(message) == false) if (mController.isCopyCapable(message) == false)
{ {
Toast toast = Toast.makeText(this, R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG); Toast toast = Toast.makeText(this,
R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
toast.show(); toast.show();
return; return;
} }
} }
} }
}
final Folder folder = mCurrentFolder.folder; final Folder folder = mCurrentFolder.folder;
final Intent intent = new Intent(this, ChooseFolder.class); final Intent intent = new Intent(this, ChooseFolder.class);
@ -3162,6 +3215,8 @@ public class MessageList
} }
List<Message> messageList = new ArrayList<Message>(); List<Message> messageList = new ArrayList<Message>();
synchronized (mAdapter.messages)
{
for (MessageInfoHolder holder : mAdapter.messages) for (MessageInfoHolder holder : mAdapter.messages)
{ {
if (holder.selected) if (holder.selected)
@ -3169,14 +3224,15 @@ public class MessageList
Message message = holder.message; Message message = holder.message;
if (mController.isCopyCapable(message) == false) if (mController.isCopyCapable(message) == false)
{ {
Toast toast = Toast.makeText(this, R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG); Toast toast = Toast.makeText(this,
R.string.move_copy_cannot_copy_unsynced_message, Toast.LENGTH_LONG);
toast.show(); toast.show();
return; return;
} }
messageList.add(holder.message); messageList.add(holder.message);
} }
} }
}
mController.copyMessages(mAccount, mCurrentFolder.name, messageList.toArray(new Message[0]), folderName, null); mController.copyMessages(mAccount, mCurrentFolder.name, messageList.toArray(new Message[0]), folderName, null);
} }
} }