mirror of
https://github.com/moparisthebest/k-9
synced 2024-12-25 00:58:50 -05:00
Fixes Issue 673
Fixes Issue 806 Make sure to close opened folders in finally blocks in MessagingController. Don't make another connection when deleting or copying a message. (Nicely speeds up copy and delete, as well.) Another connection is still created for creating a folder while copying or deleting (a pretty rare event), and the IMAP IDLE connections are not re-used for user initiated activity.
This commit is contained in:
parent
a89bd8e081
commit
f4ceb8d2bc
@ -1,6 +1,29 @@
|
||||
|
||||
package com.fsck.k9;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import android.app.Application;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
@ -8,14 +31,26 @@ import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.PowerManager;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.os.Process;
|
||||
import android.os.PowerManager.WakeLock;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.fsck.k9.activity.FolderList;
|
||||
import com.fsck.k9.mail.*;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.FetchProfile;
|
||||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.Folder;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.MessageRemovalListener;
|
||||
import com.fsck.k9.mail.MessageRetrievalListener;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mail.PushReceiver;
|
||||
import com.fsck.k9.mail.Pusher;
|
||||
import com.fsck.k9.mail.Store;
|
||||
import com.fsck.k9.mail.Transport;
|
||||
import com.fsck.k9.mail.Folder.FolderType;
|
||||
import com.fsck.k9.mail.Folder.OpenMode;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
@ -26,15 +61,6 @@ import com.fsck.k9.mail.store.LocalStore.LocalFolder;
|
||||
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
|
||||
import com.fsck.k9.mail.store.LocalStore.PendingCommand;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Starts a long running (application) Thread that will run through commands
|
||||
* that require remote mailbox access. This class is used to serialize and
|
||||
@ -392,10 +418,11 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
listener.listFoldersStarted(account);
|
||||
}
|
||||
Folder[] localFolders = null;
|
||||
try
|
||||
{
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Folder[] localFolders = localStore.getPersonalNamespaces();
|
||||
localFolders = localStore.getPersonalNamespaces();
|
||||
|
||||
if (refreshRemote || localFolders == null || localFolders.length == 0)
|
||||
{
|
||||
@ -424,6 +451,20 @@ public class MessagingController implements Runnable
|
||||
addErrorMessage(account, e);
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (localFolders != null)
|
||||
{
|
||||
for (Folder localFolder : localFolders)
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.listFoldersFinished(account);
|
||||
@ -442,6 +483,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
Folder[] localFolders = null;
|
||||
try
|
||||
{
|
||||
Store store = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
@ -460,7 +502,7 @@ public class MessagingController implements Runnable
|
||||
remoteFolderNames.add(remoteFolders[i].getName());
|
||||
}
|
||||
|
||||
Folder[] localFolders = localStore.getPersonalNamespaces();
|
||||
localFolders = localStore.getPersonalNamespaces();
|
||||
|
||||
/*
|
||||
* Clear out any folders that are no longer on the remote store.
|
||||
@ -502,6 +544,19 @@ public class MessagingController implements Runnable
|
||||
}
|
||||
addErrorMessage(account, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (localFolders != null)
|
||||
{
|
||||
for (Folder localFolder : localFolders)
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -644,14 +699,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.e(K9.LOG_TAG, "Exception while closing folder", e);
|
||||
}
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -788,6 +836,8 @@ public class MessagingController implements Runnable
|
||||
*/
|
||||
public void synchronizeMailboxSynchronous(final Account account, final String folder, final MessagingListener listener)
|
||||
{
|
||||
Folder remoteFolder = null;
|
||||
LocalFolder tLocalFolder = null;
|
||||
/*
|
||||
* We don't ever sync the Outbox or errors folder
|
||||
*/
|
||||
@ -807,7 +857,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
listener.synchronizeMailboxStarted(account, folder);
|
||||
}
|
||||
LocalFolder tLocalFolder = null;
|
||||
|
||||
Exception commandException = null;
|
||||
try
|
||||
{
|
||||
@ -853,7 +903,7 @@ public class MessagingController implements Runnable
|
||||
if (K9.DEBUG)
|
||||
Log.v(K9.LOG_TAG, "SYNC: About to get remote folder " + folder);
|
||||
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
remoteFolder = remoteStore.getFolder(folder);
|
||||
|
||||
/*
|
||||
* If the folder is a "special" folder we need to see if it exists
|
||||
@ -1005,8 +1055,6 @@ public class MessagingController implements Runnable
|
||||
localFolder.setLastChecked(System.currentTimeMillis());
|
||||
localFolder.setStatus(null);
|
||||
|
||||
remoteFolder.close();
|
||||
localFolder.close();
|
||||
if (K9.DEBUG)
|
||||
Log.d(K9.LOG_TAG, "Done synchronizing folder " +
|
||||
account.getDescription() + ":" + folder + " @ " + new Date() +
|
||||
@ -1054,7 +1102,6 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
tLocalFolder.setStatus(rootMessage);
|
||||
tLocalFolder.setLastChecked(System.currentTimeMillis());
|
||||
tLocalFolder.close();
|
||||
}
|
||||
catch (MessagingException me)
|
||||
{
|
||||
@ -1082,6 +1129,17 @@ public class MessagingController implements Runnable
|
||||
account.getDescription() + ":" + folder + " @ " + new Date());
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
remoteFolder.close();
|
||||
}
|
||||
if (tLocalFolder != null)
|
||||
{
|
||||
tLocalFolder.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1762,143 +1820,158 @@ public class MessagingController implements Runnable
|
||||
private void processPendingAppend(PendingCommand command, Account account)
|
||||
throws MessagingException
|
||||
{
|
||||
|
||||
|
||||
String folder = command.arguments[0];
|
||||
String uid = command.arguments[1];
|
||||
|
||||
if (account.getErrorFolderName().equals(folder))
|
||||
Folder remoteFolder = null;
|
||||
LocalFolder localFolder = null;
|
||||
try
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
LocalMessage localMessage = (LocalMessage) localFolder.getMessage(uid);
|
||||
|
||||
if (localMessage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
if (!remoteFolder.exists())
|
||||
{
|
||||
if (!remoteFolder.create(FolderType.HOLDS_MESSAGES))
|
||||
String folder = command.arguments[0];
|
||||
String uid = command.arguments[1];
|
||||
|
||||
if (account.getErrorFolderName().equals(folder))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Message remoteMessage = null;
|
||||
if (!localMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX))
|
||||
{
|
||||
remoteMessage = remoteFolder.getMessage(localMessage.getUid());
|
||||
}
|
||||
|
||||
if (remoteMessage == null)
|
||||
{
|
||||
if (localMessage.isSet(Flag.X_REMOTE_COPY_STARTED))
|
||||
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
LocalMessage localMessage = (LocalMessage) localFolder.getMessage(uid);
|
||||
|
||||
if (localMessage == null)
|
||||
{
|
||||
Log.w(K9.LOG_TAG, "Local message with uid " + localMessage.getUid() +
|
||||
" has flag " + Flag.X_REMOTE_COPY_STARTED + " already set, checking for remote message with " +
|
||||
" same message id");
|
||||
String rUid = remoteFolder.getUidFromMessageId(localMessage);
|
||||
if (rUid != null)
|
||||
return;
|
||||
}
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
remoteFolder = remoteStore.getFolder(folder);
|
||||
if (!remoteFolder.exists())
|
||||
{
|
||||
if (!remoteFolder.create(FolderType.HOLDS_MESSAGES))
|
||||
{
|
||||
Log.w(K9.LOG_TAG, "Local message has flag " + Flag.X_REMOTE_COPY_STARTED + " already set, and there is a remote message with " +
|
||||
" uid " + rUid + ", assuming message was already copied and aborting this copy");
|
||||
|
||||
String oldUid = localMessage.getUid();
|
||||
localMessage.setUid(rUid);
|
||||
localFolder.changeUid(localMessage);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
}
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Message remoteMessage = null;
|
||||
if (!localMessage.getUid().startsWith(K9.LOCAL_UID_PREFIX))
|
||||
{
|
||||
remoteMessage = remoteFolder.getMessage(localMessage.getUid());
|
||||
}
|
||||
|
||||
if (remoteMessage == null)
|
||||
{
|
||||
if (localMessage.isSet(Flag.X_REMOTE_COPY_STARTED))
|
||||
{
|
||||
Log.w(K9.LOG_TAG, "No remote message with message-id found, proceeding with append");
|
||||
Log.w(K9.LOG_TAG, "Local message with uid " + localMessage.getUid() +
|
||||
" has flag " + Flag.X_REMOTE_COPY_STARTED + " already set, checking for remote message with " +
|
||||
" same message id");
|
||||
String rUid = remoteFolder.getUidFromMessageId(localMessage);
|
||||
if (rUid != null)
|
||||
{
|
||||
Log.w(K9.LOG_TAG, "Local message has flag " + Flag.X_REMOTE_COPY_STARTED + " already set, and there is a remote message with " +
|
||||
" uid " + rUid + ", assuming message was already copied and aborting this copy");
|
||||
|
||||
String oldUid = localMessage.getUid();
|
||||
localMessage.setUid(rUid);
|
||||
localFolder.changeUid(localMessage);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.w(K9.LOG_TAG, "No remote message with message-id found, proceeding with append");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the message does not exist remotely we just upload it and then
|
||||
* update our local copy with the new uid.
|
||||
*/
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localFolder.fetch(new Message[]
|
||||
{
|
||||
localMessage
|
||||
}
|
||||
, fp, null);
|
||||
String oldUid = localMessage.getUid();
|
||||
localMessage.setFlag(Flag.X_REMOTE_COPY_STARTED, true);
|
||||
remoteFolder.appendMessages(new Message[] { localMessage });
|
||||
|
||||
localFolder.changeUid(localMessage);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If the remote message exists we need to determine which copy to keep.
|
||||
*/
|
||||
/*
|
||||
* See if the remote message is newer than ours.
|
||||
*/
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
|
||||
Date localDate = localMessage.getInternalDate();
|
||||
Date remoteDate = remoteMessage.getInternalDate();
|
||||
if (remoteDate.compareTo(localDate) > 0)
|
||||
{
|
||||
|
||||
/*
|
||||
* If the remote message is newer than ours we'll just
|
||||
* delete ours and move on. A sync will get the server message
|
||||
* if we need to be able to see it.
|
||||
* If the message does not exist remotely we just upload it and then
|
||||
* update our local copy with the new uid.
|
||||
*/
|
||||
localMessage.setFlag(Flag.DELETED, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Otherwise we'll upload our message and then delete the remote message.
|
||||
*/
|
||||
fp.clear();
|
||||
fp = new FetchProfile();
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localFolder.fetch(new Message[] { localMessage }, fp, null);
|
||||
localFolder.fetch(new Message[]
|
||||
{
|
||||
localMessage
|
||||
}
|
||||
, fp, null);
|
||||
String oldUid = localMessage.getUid();
|
||||
|
||||
localMessage.setFlag(Flag.X_REMOTE_COPY_STARTED, true);
|
||||
|
||||
remoteFolder.appendMessages(new Message[] { localMessage });
|
||||
|
||||
localFolder.changeUid(localMessage);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
||||
}
|
||||
remoteMessage.setFlag(Flag.DELETED, true);
|
||||
if (Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy()))
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If the remote message exists we need to determine which copy to keep.
|
||||
*/
|
||||
/*
|
||||
* See if the remote message is newer than ours.
|
||||
*/
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
|
||||
Date localDate = localMessage.getInternalDate();
|
||||
Date remoteDate = remoteMessage.getInternalDate();
|
||||
if (remoteDate.compareTo(localDate) > 0)
|
||||
{
|
||||
remoteFolder.expunge();
|
||||
/*
|
||||
* If the remote message is newer than ours we'll just
|
||||
* delete ours and move on. A sync will get the server message
|
||||
* if we need to be able to see it.
|
||||
*/
|
||||
localMessage.setFlag(Flag.DELETED, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Otherwise we'll upload our message and then delete the remote message.
|
||||
*/
|
||||
fp.clear();
|
||||
fp = new FetchProfile();
|
||||
fp.add(FetchProfile.Item.BODY);
|
||||
localFolder.fetch(new Message[] { localMessage }, fp, null);
|
||||
String oldUid = localMessage.getUid();
|
||||
|
||||
localMessage.setFlag(Flag.X_REMOTE_COPY_STARTED, true);
|
||||
|
||||
remoteFolder.appendMessages(new Message[] { localMessage });
|
||||
localFolder.changeUid(localMessage);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.messageUidChanged(account, folder, oldUid, localMessage.getUid());
|
||||
}
|
||||
remoteMessage.setFlag(Flag.DELETED, true);
|
||||
if (Account.EXPUNGE_IMMEDIATELY.equals(account.getExpungePolicy()))
|
||||
{
|
||||
remoteFolder.expunge();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
remoteFolder.close();
|
||||
}
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1992,12 +2065,6 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
remoteDestFolder = remoteStore.getFolder(destFolder);
|
||||
|
||||
remoteDestFolder.open(OpenMode.READ_WRITE);
|
||||
if (remoteDestFolder.getMode() != OpenMode.READ_WRITE)
|
||||
{
|
||||
throw new MessagingException("processingPendingMoveOrCopy: could not open remoteDestFolder " + srcFolder + " read/write", true);
|
||||
}
|
||||
|
||||
if (isCopy)
|
||||
{
|
||||
remoteSrcFolder.copyMessages(messages.toArray(new Message[0]), remoteDestFolder);
|
||||
@ -2117,7 +2184,7 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
String folder = command.arguments[0];
|
||||
String uid = command.arguments[1];
|
||||
|
||||
|
||||
if (account.getErrorFolderName().equals(folder))
|
||||
{
|
||||
return;
|
||||
@ -2128,28 +2195,38 @@ public class MessagingController implements Runnable
|
||||
boolean newState = Boolean.parseBoolean(command.arguments[2]);
|
||||
|
||||
Flag flag = Flag.valueOf(command.arguments[3]);
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
if (!remoteFolder.exists())
|
||||
Folder remoteFolder = null;
|
||||
try
|
||||
{
|
||||
return;
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
remoteFolder = remoteStore.getFolder(folder);
|
||||
if (!remoteFolder.exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Message remoteMessage = null;
|
||||
if (!uid.startsWith(K9.LOCAL_UID_PREFIX))
|
||||
{
|
||||
remoteMessage = remoteFolder.getMessage(uid);
|
||||
}
|
||||
if (remoteMessage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
remoteMessage.setFlag(flag, newState);
|
||||
}
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
if (remoteFolder.getMode() != OpenMode.READ_WRITE)
|
||||
finally
|
||||
{
|
||||
return;
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
remoteFolder.close();
|
||||
}
|
||||
}
|
||||
Message remoteMessage = null;
|
||||
if (!uid.startsWith(K9.LOCAL_UID_PREFIX))
|
||||
{
|
||||
remoteMessage = remoteFolder.getMessage(uid);
|
||||
}
|
||||
if (remoteMessage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
remoteMessage.setFlag(flag, newState);
|
||||
}
|
||||
private void queueExpunge(final Account account, final String folderName)
|
||||
{
|
||||
@ -2287,36 +2364,39 @@ public class MessagingController implements Runnable
|
||||
private void processPendingMarkAllAsRead(PendingCommand command, Account account) throws MessagingException
|
||||
{
|
||||
String folder = command.arguments[0];
|
||||
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
Message[] messages = localFolder.getMessages(null, false);
|
||||
for (Message message : messages)
|
||||
{
|
||||
if (message.isSet(Flag.SEEN) == false)
|
||||
{
|
||||
message.setFlag(Flag.SEEN, true);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.listLocalMessagesUpdateMessage(account, folder, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
localFolder.setUnreadMessageCount(0);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.folderStatusChanged(account, folder, 0);
|
||||
}
|
||||
Folder remoteFolder = null;
|
||||
LocalFolder localFolder = null;
|
||||
try
|
||||
{
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
Message[] messages = localFolder.getMessages(null, false);
|
||||
for (Message message : messages)
|
||||
{
|
||||
if (message.isSet(Flag.SEEN) == false)
|
||||
{
|
||||
message.setFlag(Flag.SEEN, true);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.listLocalMessagesUpdateMessage(account, folder, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
localFolder.setUnreadMessageCount(0);
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.folderStatusChanged(account, folder, 0);
|
||||
}
|
||||
|
||||
|
||||
if (account.getErrorFolderName().equals(folder))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
remoteFolder = remoteStore.getFolder(folder);
|
||||
|
||||
if (!remoteFolder.exists())
|
||||
{
|
||||
@ -2337,7 +2417,14 @@ public class MessagingController implements Runnable
|
||||
}
|
||||
finally
|
||||
{
|
||||
localFolder.close();
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
remoteFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2821,6 +2908,8 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
Folder remoteFolder = null;
|
||||
LocalFolder localFolder = null;
|
||||
try
|
||||
{
|
||||
LocalStore localStore =
|
||||
@ -2840,16 +2929,15 @@ public class MessagingController implements Runnable
|
||||
attachment.setBody(null);
|
||||
}
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
LocalFolder localFolder =
|
||||
localFolder =
|
||||
(LocalFolder) localStore.getFolder(message.getFolder().getName());
|
||||
Folder remoteFolder = remoteStore.getFolder(message.getFolder().getName());
|
||||
remoteFolder = remoteStore.getFolder(message.getFolder().getName());
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
FetchProfile fp = new FetchProfile();
|
||||
fp.add(part);
|
||||
remoteFolder.fetch(new Message[] { message }, fp, null);
|
||||
localFolder.updateMessage((LocalMessage)message);
|
||||
localFolder.close();
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
l.loadAttachmentFinished(account, message, part, tag);
|
||||
@ -2875,6 +2963,17 @@ public class MessagingController implements Runnable
|
||||
addErrorMessage(account, me);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (remoteFolder != null)
|
||||
{
|
||||
remoteFolder.close();
|
||||
}
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -2936,9 +3035,9 @@ public class MessagingController implements Runnable
|
||||
|
||||
public boolean messagesPendingSend(final Account account)
|
||||
{
|
||||
Folder localFolder = null;
|
||||
try
|
||||
{
|
||||
Folder localFolder = null;
|
||||
Store localStore = Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
@ -2952,7 +3051,6 @@ public class MessagingController implements Runnable
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
int localMessages = localFolder.getMessageCount();
|
||||
localFolder.close();
|
||||
if (localMessages > 0)
|
||||
{
|
||||
return true;
|
||||
@ -2962,6 +3060,13 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
Log.e(K9.LOG_TAG, "Exception while checking for unsent messages", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3595,13 +3700,13 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
Folder localFolder = null;
|
||||
try
|
||||
{
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Folder localFolder = localStore.getFolder(account.getTrashFolderName());
|
||||
localFolder = localStore.getFolder(account.getTrashFolderName());
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
localFolder.setFlags(new Flag[] { Flag.DELETED }, true);
|
||||
localFolder.close();
|
||||
|
||||
for (MessagingListener l : getListeners())
|
||||
{
|
||||
@ -3620,6 +3725,13 @@ public class MessagingController implements Runnable
|
||||
|
||||
addErrorMessage(account, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -3838,13 +3950,14 @@ public class MessagingController implements Runnable
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
LocalFolder tLocalFolder = null;
|
||||
try
|
||||
{
|
||||
// In case multiple Commands get enqueued, don't run more than
|
||||
// once
|
||||
final LocalStore localStore =
|
||||
(LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
LocalFolder tLocalFolder = (LocalFolder) localStore.getFolder(folder.getName());
|
||||
tLocalFolder = (LocalFolder) localStore.getFolder(folder.getName());
|
||||
tLocalFolder.open(Folder.OpenMode.READ_WRITE);
|
||||
|
||||
if (ignoreLastCheckedTime == false && tLocalFolder.getLastChecked() >
|
||||
@ -3897,6 +4010,13 @@ public class MessagingController implements Runnable
|
||||
account.getDescription() + ":" + folder.getName(), e);
|
||||
addErrorMessage(account, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tLocalFolder != null)
|
||||
{
|
||||
tLocalFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -3907,6 +4027,7 @@ public class MessagingController implements Runnable
|
||||
Log.e(K9.LOG_TAG, "Unable to synchronize account " + account.getName(), e);
|
||||
addErrorMessage(account, e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -118,14 +118,7 @@ public class MessagingControllerPushReceiver implements PushReceiver
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.e(K9.LOG_TAG, "Unable to close folder '" + folderName + "' in account " + account.getDescription(), e);
|
||||
}
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -913,11 +913,12 @@ public class FolderList extends K9ListActivity
|
||||
private void refreshFolder(Account account, String folderName)
|
||||
{
|
||||
// There has to be a cheaper way to get at the localFolder object than this
|
||||
Folder localFolder = null;
|
||||
try
|
||||
{
|
||||
if (account != null && folderName != null)
|
||||
{
|
||||
Folder localFolder = (Folder) Store.getInstance(account.getLocalStoreUri(), getApplication()).getFolder(folderName);
|
||||
localFolder = (Folder) Store.getInstance(account.getLocalStoreUri(), getApplication()).getFolder(folderName);
|
||||
int unreadMessageCount = localFolder.getUnreadMessageCount();
|
||||
if (localFolder != null)
|
||||
{
|
||||
@ -934,6 +935,13 @@ public class FolderList extends K9ListActivity
|
||||
{
|
||||
Log.e(K9.LOG_TAG, "Exception while populating folder", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (localFolder != null)
|
||||
{
|
||||
localFolder.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -610,6 +610,26 @@ public class ImapStore extends Store
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
private boolean exists(String folderName) throws MessagingException
|
||||
{
|
||||
try
|
||||
{
|
||||
// Since we don't care about RECENT, we'll use that for the check, because we're checking
|
||||
// a folder other than ourself, and don't want any untagged responses to cause a change
|
||||
// in our own fields
|
||||
mConnection.executeSimpleCommand(String.format("STATUS \"%s\" (RECENT)", folderName));
|
||||
return true;
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw ioExceptionHandler(mConnection, ioe);
|
||||
}
|
||||
catch (MessagingException me)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean exists() throws MessagingException
|
||||
{
|
||||
@ -720,9 +740,30 @@ public class ImapStore extends Store
|
||||
}
|
||||
try
|
||||
{
|
||||
executeSimpleCommand(String.format("UID COPY %s \"%s\"",
|
||||
Utility.combine(uids, ','),
|
||||
encodeFolderName(iFolder.getPrefixedName())));
|
||||
String remoteDestName = encodeFolderName(iFolder.getPrefixedName());
|
||||
|
||||
if (!exists(remoteDestName))
|
||||
{
|
||||
/*
|
||||
* If the remote trash folder doesn't exist we try to create it.
|
||||
*/
|
||||
if (K9.DEBUG)
|
||||
Log.i(K9.LOG_TAG, "IMAPMessage.copyMessages: attempting to create remote '" + remoteDestName + "' folder for " + getLogId());
|
||||
iFolder.create(FolderType.HOLDS_MESSAGES);
|
||||
}
|
||||
|
||||
if (exists(remoteDestName))
|
||||
{
|
||||
executeSimpleCommand(String.format("UID COPY %s \"%s\"",
|
||||
Utility.combine(uids, ','),
|
||||
encodeFolderName(iFolder.getPrefixedName())));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new MessagingException("IMAPMessage.copyMessages: remote destination folder " + folder.getName()
|
||||
+ " does not exist and could not be created for " + getLogId()
|
||||
, true);
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
@ -751,11 +792,9 @@ public class ImapStore extends Store
|
||||
else
|
||||
{
|
||||
ImapFolder remoteTrashFolder = (ImapFolder)getStore().getFolder(trashFolderName);
|
||||
/*
|
||||
* Attempt to copy the remote message to the remote trash folder.
|
||||
*/
|
||||
remoteTrashFolder.mExists = false; // Force redetection of Trash folder; some desktops delete it
|
||||
if (!remoteTrashFolder.exists())
|
||||
String remoteTrashName = encodeFolderName(remoteTrashFolder.getPrefixedName());
|
||||
|
||||
if (!exists(remoteTrashName))
|
||||
{
|
||||
/*
|
||||
* If the remote trash folder doesn't exist we try to create it.
|
||||
@ -765,7 +804,7 @@ public class ImapStore extends Store
|
||||
remoteTrashFolder.create(FolderType.HOLDS_MESSAGES);
|
||||
}
|
||||
|
||||
if (remoteTrashFolder.exists())
|
||||
if (exists(remoteTrashName))
|
||||
{
|
||||
if (K9.DEBUG)
|
||||
Log.d(K9.LOG_TAG, "IMAPMessage.delete: copying remote " + messages.length + " messages to '" + trashFolderName + "' for " + getLogId());
|
||||
@ -1014,7 +1053,7 @@ public class ImapStore extends Store
|
||||
}
|
||||
for (Object o : fp)
|
||||
{
|
||||
if (o instanceof Part)
|
||||
if (o != null && o instanceof Part)
|
||||
{
|
||||
Part part = (Part) o;
|
||||
String partId = part.getHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA)[0];
|
||||
|
Loading…
Reference in New Issue
Block a user