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:
parent
7b63c8091c
commit
e3cb9f4603
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user