mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-15 06:30:17 -05:00
Keep the sync state of a remote EasFolder in sync with its local counterpart when synchronizing the folder.
This commit is contained in:
parent
474780cbf4
commit
a212965b99
@ -64,7 +64,6 @@ import com.fsck.k9.mail.store.UnavailableStorageException;
|
|||||||
import com.fsck.k9.mail.store.LocalStore.LocalFolder;
|
import com.fsck.k9.mail.store.LocalStore.LocalFolder;
|
||||||
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
|
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
|
||||||
import com.fsck.k9.mail.store.LocalStore.PendingCommand;
|
import com.fsck.k9.mail.store.LocalStore.PendingCommand;
|
||||||
import com.fsck.k9.mail.store.EasStore.EasFolder;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -503,28 +502,21 @@ public class MessagingController implements Runnable {
|
|||||||
private void syncLocalFoldersWithRemoteFolders(List<? extends Folder> localFolders,
|
private void syncLocalFoldersWithRemoteFolders(List<? extends Folder> localFolders,
|
||||||
List<? extends Folder> remoteFolders, final Account account) throws MessagingException {
|
List<? extends Folder> remoteFolders, final Account account) throws MessagingException {
|
||||||
HashSet<String> remoteFolderNames = new HashSet<String>();
|
HashSet<String> remoteFolderNames = new HashSet<String>();
|
||||||
HashMap<String, Folder> localFolderNames = new HashMap<String, Folder>();
|
HashSet<String> localFolderNames = new HashSet<String>();
|
||||||
|
|
||||||
List<LocalFolder> foldersToCreate = new LinkedList<LocalFolder>();
|
List<LocalFolder> foldersToCreate = new LinkedList<LocalFolder>();
|
||||||
LocalStore localStore = account.getLocalStore();
|
LocalStore localStore = account.getLocalStore();
|
||||||
|
|
||||||
for (Folder localFolder : localFolders) {
|
for (Folder localFolder : localFolders) {
|
||||||
localFolderNames.put(localFolder.getRemoteName(), localFolder);
|
localFolderNames.add(localFolder.getRemoteName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any new folders in the remote store to the local store.
|
// Add any new folders in the remote store to the local store.
|
||||||
for (Folder remoteFolder : remoteFolders) {
|
for (Folder remoteFolder : remoteFolders) {
|
||||||
LocalFolder localFolder = (LocalFolder)localFolderNames.get(remoteFolder.getRemoteName());
|
if (!localFolderNames.contains(remoteFolder.getRemoteName())) {
|
||||||
if (localFolder == null) {
|
foldersToCreate.add(localStore.getFolder(remoteFolder.getRemoteName(), remoteFolder.getName()));
|
||||||
localFolder = localStore.getFolder(remoteFolder.getRemoteName(),
|
|
||||||
remoteFolder.getName());
|
|
||||||
foldersToCreate.add(localFolder);
|
|
||||||
}
|
}
|
||||||
remoteFolderNames.add(remoteFolder.getRemoteName());
|
remoteFolderNames.add(remoteFolder.getRemoteName());
|
||||||
|
|
||||||
if (remoteFolder instanceof EasFolder) {
|
|
||||||
((EasFolder)remoteFolder).setLocalFolder(localFolder, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
localStore.createFolders(foldersToCreate, account.getDisplayCount());
|
localStore.createFolders(foldersToCreate, account.getDisplayCount());
|
||||||
@ -849,7 +841,9 @@ public class MessagingController implements Runnable {
|
|||||||
* TODO Break this method up into smaller chunks.
|
* TODO Break this method up into smaller chunks.
|
||||||
* @param providedRemoteFolder TODO
|
* @param providedRemoteFolder TODO
|
||||||
*/
|
*/
|
||||||
private void synchronizeMailboxSynchronous(final Account account, final String folder, final MessagingListener listener, Folder providedRemoteFolder) {
|
private void synchronizeMailboxSynchronous(final Account account, final String folder,
|
||||||
|
final MessagingListener listener, Folder providedRemoteFolder) {
|
||||||
|
Store remoteStore = null;
|
||||||
Folder remoteFolder = null;
|
Folder remoteFolder = null;
|
||||||
LocalFolder tLocalFolder = null;
|
LocalFolder tLocalFolder = null;
|
||||||
|
|
||||||
@ -859,6 +853,7 @@ public class MessagingController implements Runnable {
|
|||||||
for (MessagingListener l : getListeners(listener)) {
|
for (MessagingListener l : getListeners(listener)) {
|
||||||
l.synchronizeMailboxStarted(account, folder);
|
l.synchronizeMailboxStarted(account, folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't ever sync the Outbox or errors folder
|
* We don't ever sync the Outbox or errors folder
|
||||||
*/
|
*/
|
||||||
@ -907,17 +902,17 @@ public class MessagingController implements Runnable {
|
|||||||
Log.v(K9.LOG_TAG, "SYNC: using providedRemoteFolder " + folder);
|
Log.v(K9.LOG_TAG, "SYNC: using providedRemoteFolder " + folder);
|
||||||
remoteFolder = providedRemoteFolder;
|
remoteFolder = providedRemoteFolder;
|
||||||
} else {
|
} else {
|
||||||
Store remoteStore = account.getRemoteStore();
|
remoteStore = account.getRemoteStore();
|
||||||
|
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.v(K9.LOG_TAG, "SYNC: About to get remote folder " + folder);
|
Log.v(K9.LOG_TAG, "SYNC: About to get remote folder " + folder);
|
||||||
|
|
||||||
remoteFolder = remoteStore.getFolder(folder);
|
remoteFolder = remoteStore.getFolder(folder);
|
||||||
|
|
||||||
if (remoteFolder == null) {
|
if (remoteFolder == null) {
|
||||||
throw new Exception("Store returned null remote folder for " + folder);
|
throw new Exception("Attempted to synchronize a local-only folder " + folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! verifyOrCreateRemoteSpecialFolder(account, folder, remoteFolder, listener)) {
|
if (!verifyOrCreateRemoteSpecialFolder(account, folder, remoteFolder, listener)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,7 +946,6 @@ public class MessagingController implements Runnable {
|
|||||||
Log.d(K9.LOG_TAG, "SYNC: Expunging folder " + account.getDescription() + ":" + folder);
|
Log.d(K9.LOG_TAG, "SYNC: Expunging folder " + account.getDescription() + ":" + folder);
|
||||||
remoteFolder.expunge();
|
remoteFolder.expunge();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -975,7 +969,6 @@ public class MessagingController implements Runnable {
|
|||||||
Log.v(K9.LOG_TAG, "SYNC: Remote message count for folder " + folder + " is " + remoteMessageCount);
|
Log.v(K9.LOG_TAG, "SYNC: Remote message count for folder " + folder + " is " + remoteMessageCount);
|
||||||
final Date earliestDate = account.getEarliestPollDate();
|
final Date earliestDate = account.getEarliestPollDate();
|
||||||
|
|
||||||
|
|
||||||
if (remoteMessageCount > 0 || syncMode) {
|
if (remoteMessageCount > 0 || syncMode) {
|
||||||
/* Message numbers start at 1. */
|
/* Message numbers start at 1. */
|
||||||
int remoteStart;
|
int remoteStart;
|
||||||
@ -994,7 +987,6 @@ public class MessagingController implements Runnable {
|
|||||||
l.synchronizeMailboxHeadersStarted(account, folder);
|
l.synchronizeMailboxHeadersStarted(account, folder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
remoteMessageArray = remoteFolder.getMessages(remoteStart, remoteEnd, earliestDate, null);
|
remoteMessageArray = remoteFolder.getMessages(remoteStart, remoteEnd, earliestDate, null);
|
||||||
|
|
||||||
int messageCount = remoteMessageArray.length;
|
int messageCount = remoteMessageArray.length;
|
||||||
@ -1042,7 +1034,6 @@ public class MessagingController implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
localFolder.destroyMessages(destroyMessages.toArray(EMPTY_MESSAGE_ARRAY));
|
localFolder.destroyMessages(destroyMessages.toArray(EMPTY_MESSAGE_ARRAY));
|
||||||
|
|
||||||
for (Message destroyMessage : destroyMessages) {
|
for (Message destroyMessage : destroyMessages) {
|
||||||
@ -1061,7 +1052,6 @@ public class MessagingController implements Runnable {
|
|||||||
int unreadMessageCount = setLocalUnreadCountToRemote(localFolder, remoteFolder, newMessages);
|
int unreadMessageCount = setLocalUnreadCountToRemote(localFolder, remoteFolder, newMessages);
|
||||||
setLocalFlaggedCountToRemote(localFolder, remoteFolder);
|
setLocalFlaggedCountToRemote(localFolder, remoteFolder);
|
||||||
|
|
||||||
|
|
||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
l.folderStatusChanged(account, folder, unreadMessageCount);
|
l.folderStatusChanged(account, folder, unreadMessageCount);
|
||||||
}
|
}
|
||||||
@ -1079,7 +1069,6 @@ public class MessagingController implements Runnable {
|
|||||||
l.synchronizeMailboxFinished(account, folder, remoteMessageCount, newMessages);
|
l.synchronizeMailboxFinished(account, folder, remoteMessageCount, newMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (commandException != null) {
|
if (commandException != null) {
|
||||||
String rootMessage = getRootCauseMessage(commandException);
|
String rootMessage = getRootCauseMessage(commandException);
|
||||||
Log.e(K9.LOG_TAG, "Root cause failure in " + account.getDescription() + ":" +
|
Log.e(K9.LOG_TAG, "Root cause failure in " + account.getDescription() + ":" +
|
||||||
@ -1115,13 +1104,25 @@ public class MessagingController implements Runnable {
|
|||||||
Log.e(K9.LOG_TAG, "Failed synchronizing folder " + account.getDescription() + ":" + folder + " @ " + new Date());
|
Log.e(K9.LOG_TAG, "Failed synchronizing folder " + account.getDescription() + ":" + folder + " @ " + new Date());
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
// For certain store types, we need to make sure to keep the push state of the local
|
||||||
|
// and remote folder in sync.
|
||||||
|
if (remoteStore.keepPushStateInSync()) {
|
||||||
|
if (remoteFolder != null && tLocalFolder != null) {
|
||||||
|
try {
|
||||||
|
tLocalFolder.setPushState(remoteFolder.getPushState());
|
||||||
|
}
|
||||||
|
catch (MessagingException e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Unable to update the local push state for folder " + tLocalFolder.getName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (providedRemoteFolder == null) {
|
if (providedRemoteFolder == null) {
|
||||||
closeFolder(remoteFolder);
|
closeFolder(remoteFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
closeFolder(tLocalFolder);
|
closeFolder(tLocalFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -223,4 +223,8 @@ public abstract class Folder {
|
|||||||
public boolean isSyncMode() {
|
public boolean isSyncMode() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPushState() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,6 +175,10 @@ public abstract class Store {
|
|||||||
public boolean isExpungeCapable() {
|
public boolean isExpungeCapable() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean keepPushStateInSync() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public void sendMessages(Message[] messages) throws MessagingException {
|
public void sendMessages(Message[] messages) throws MessagingException {
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,6 @@ import com.fsck.k9.mail.ServerSettings;
|
|||||||
import com.fsck.k9.mail.Store;
|
import com.fsck.k9.mail.Store;
|
||||||
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
||||||
import com.fsck.k9.mail.internet.MimeMessage;
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
import com.fsck.k9.mail.store.LocalStore.LocalFolder;
|
|
||||||
import com.fsck.k9.mail.store.exchange.Eas;
|
import com.fsck.k9.mail.store.exchange.Eas;
|
||||||
import com.fsck.k9.mail.store.exchange.adapter.EasEmailSyncParser;
|
import com.fsck.k9.mail.store.exchange.adapter.EasEmailSyncParser;
|
||||||
import com.fsck.k9.mail.store.exchange.adapter.FolderSyncParser;
|
import com.fsck.k9.mail.store.exchange.adapter.FolderSyncParser;
|
||||||
@ -802,6 +801,7 @@ public class EasStore extends Store {
|
|||||||
throw new MessagingException("io", e);
|
throw new MessagingException("io", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EASTODO: This needs to preserve the sync key for each folder.
|
||||||
synchronized (mFolderList) {
|
synchronized (mFolderList) {
|
||||||
mFolderList.clear();
|
mFolderList.clear();
|
||||||
for (Folder folder : folderList) {
|
for (Folder folder : folderList) {
|
||||||
@ -868,7 +868,7 @@ public class EasStore extends Store {
|
|||||||
|
|
||||||
EasFolder remoteFolder = new EasFolder(folder.getName(), folder.getRemoteName(), type);
|
EasFolder remoteFolder = new EasFolder(folder.getName(), folder.getRemoteName(), type);
|
||||||
mFolderList.put(folder.getRemoteName(), remoteFolder);
|
mFolderList.put(folder.getRemoteName(), remoteFolder);
|
||||||
remoteFolder.setLocalFolder((LocalFolder)folder, true);
|
remoteFolder.setSyncKey(folder.getPushState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -908,6 +908,11 @@ public class EasStore extends Store {
|
|||||||
public boolean isSendCapable() {
|
public boolean isSendCapable() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean keepPushStateInSync() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessages(Message[] messages) throws MessagingException {
|
public void sendMessages(Message[] messages) throws MessagingException {
|
||||||
@ -999,7 +1004,6 @@ public class EasStore extends Store {
|
|||||||
private int mType;
|
private int mType;
|
||||||
private boolean mIsOpen = false;
|
private boolean mIsOpen = false;
|
||||||
private String mSyncKey = null;
|
private String mSyncKey = null;
|
||||||
private LocalFolder mLocalFolder = null;
|
|
||||||
|
|
||||||
protected EasStore getStore() {
|
protected EasStore getStore() {
|
||||||
return EasStore.this;
|
return EasStore.this;
|
||||||
@ -1012,16 +1016,6 @@ public class EasStore extends Store {
|
|||||||
mType = type;
|
mType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocalFolder(LocalFolder folder, boolean setSyncKey) {
|
|
||||||
mLocalFolder = folder;
|
|
||||||
if (setSyncKey && mLocalFolder != null) {
|
|
||||||
if (mSyncKey != null && !mSyncKey.equals(INITIAL_SYNC_KEY)) {
|
|
||||||
Log.d(K9.LOG_TAG, "Overriding non-default SyncKey: " + mSyncKey);
|
|
||||||
}
|
|
||||||
mSyncKey = mLocalFolder.getPushState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSyncKey() throws MessagingException {
|
public String getSyncKey() throws MessagingException {
|
||||||
if (mSyncKey == null) {
|
if (mSyncKey == null) {
|
||||||
Log.d(K9.LOG_TAG, "Reset SyncKey to 0");
|
Log.d(K9.LOG_TAG, "Reset SyncKey to 0");
|
||||||
@ -1032,9 +1026,6 @@ public class EasStore extends Store {
|
|||||||
|
|
||||||
public void setSyncKey(String key) throws MessagingException {
|
public void setSyncKey(String key) throws MessagingException {
|
||||||
mSyncKey = key;
|
mSyncKey = key;
|
||||||
if (mLocalFolder != null) {
|
|
||||||
mLocalFolder.setPushState(mSyncKey);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1449,10 +1440,15 @@ public class EasStore extends Store {
|
|||||||
"Unimplemented method setFlags(Flag[], boolean) breaks markAllMessagesAsRead and EmptyTrash");
|
"Unimplemented method setFlags(Flag[], boolean) breaks markAllMessagesAsRead and EmptyTrash");
|
||||||
// Try to make this efficient by not retrieving all of the messages
|
// Try to make this efficient by not retrieving all of the messages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPushState() {
|
||||||
|
return mSyncKey;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getNewPushState(String oldPushState, Message message) {
|
public String getNewPushState(String oldPushState, Message message) {
|
||||||
return mSyncKey;
|
return getPushState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1419,9 +1419,11 @@ public class LocalStore extends Store implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getPushState() {
|
public String getPushState() {
|
||||||
return mPushState;
|
return mPushState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FolderClass getDisplayClass() {
|
public FolderClass getDisplayClass() {
|
||||||
return mDisplayClass;
|
return mDisplayClass;
|
||||||
|
Loading…
Reference in New Issue
Block a user