mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-30 13:12:25 -05:00
Handle aborted imap searches by nuking in-progress connections.
This commit is contained in:
parent
9f96cd36a7
commit
2541753aff
@ -8,6 +8,7 @@ import java.util.EnumMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
@ -72,6 +73,8 @@ import com.fsck.k9.helper.Utility;
|
||||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.Folder;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.Store;
|
||||
import com.fsck.k9.mail.store.ImapStore;
|
||||
import com.fsck.k9.mail.store.LocalStore;
|
||||
import com.fsck.k9.mail.store.LocalStore.LocalFolder;
|
||||
import com.fsck.k9.mail.store.StorageManager;
|
||||
@ -300,6 +303,7 @@ public class MessageList extends K9ListActivity implements OnItemClickListener {
|
||||
private boolean mRemoteSearch = false;
|
||||
private String mSearchAccount = null;
|
||||
private String mSearchFolder = null;
|
||||
private Future mRemoteSearchFuture = null;
|
||||
private boolean mIntegrate = false;
|
||||
private String[] mAccountUuids = null;
|
||||
private String[] mFolderNames = null;
|
||||
@ -983,7 +987,7 @@ public class MessageList extends K9ListActivity implements OnItemClickListener {
|
||||
if (mAdapter.isEmpty()) {
|
||||
if (mRemoteSearch) {
|
||||
//TODO: Support flag based search
|
||||
mController.searchRemoteMessages(mSearchAccount, mSearchFolder, mQueryString, null, null, mAdapter.mListener);
|
||||
mRemoteSearchFuture = mController.searchRemoteMessages(mSearchAccount, mSearchFolder, mQueryString, null, null, mAdapter.mListener);
|
||||
} else if (mFolderName != null) {
|
||||
mController.listLocalMessages(mAccount, mFolderName, mAdapter.mListener);
|
||||
// Hide the archive button if we don't have an archive folder.
|
||||
@ -1585,6 +1589,36 @@ public class MessageList extends K9ListActivity implements OnItemClickListener {
|
||||
mController.sendPendingMessages(account, mAdapter.mListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to do some special clean up when leaving a remote search result screen. If no remote search is
|
||||
* in progress, this method does nothing special.
|
||||
*/
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// If we represent a remote search, then kill that before going back.
|
||||
if(mSearchAccount != null && mSearchFolder != null && mRemoteSearchFuture != null) {
|
||||
try {
|
||||
Log.i(K9.LOG_TAG, "Remote search in progress, attempting to abort...");
|
||||
// Canceling the future stops any message fetches in progress.
|
||||
final boolean cancelSuccess = mRemoteSearchFuture.cancel(true); // mayInterruptIfRunning = true
|
||||
if (!cancelSuccess) {
|
||||
Log.e(K9.LOG_TAG, "Could not cancel remote search future.");
|
||||
}
|
||||
// Closing the folder will kill off the connection if we're mid-search.
|
||||
final Account searchAccount = Preferences.getPreferences(this).getAccount(mSearchAccount);
|
||||
final Store remoteStore = searchAccount.getRemoteStore();
|
||||
final Folder remoteFolder = remoteStore.getFolder(mSearchFolder);
|
||||
remoteFolder.close();
|
||||
// Send a remoteSearchFinished() message for good measure.
|
||||
mAdapter.mListener.remoteSearchFinished(searchAccount, mSearchFolder, 0, null);
|
||||
} catch (Exception e) {
|
||||
// Since the user is going back, log and squash any exceptions.
|
||||
Log.e(K9.LOG_TAG, "Could not abort remote search before going back", e);
|
||||
}
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int itemId = item.getItemId();
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
package com.fsck.k9.controller;
|
||||
|
||||
import java.io.CharArrayWriter;
|
||||
@ -16,13 +15,7 @@ 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.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@ -790,7 +783,7 @@ public class MessagingController implements Runnable {
|
||||
|
||||
|
||||
|
||||
public void searchRemoteMessages(final String acctUuid, final String folderName, final String query, final Flag[] requiredFlags, final Flag[] forbiddenFlags, final MessagingListener listener) {
|
||||
public Future searchRemoteMessages(final String acctUuid, final String folderName, final String query, final Flag[] requiredFlags, final Flag[] forbiddenFlags, final MessagingListener listener) {
|
||||
if (K9.DEBUG) {
|
||||
String msg = "searchRemoteMessages ("
|
||||
+ "acct=" + acctUuid
|
||||
@ -800,7 +793,7 @@ public class MessagingController implements Runnable {
|
||||
Log.i(K9.LOG_TAG, msg);
|
||||
}
|
||||
|
||||
threadPool.execute(new Runnable() {
|
||||
return threadPool.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
searchRemoteMessagesSynchronous(acctUuid, folderName, query, requiredFlags, forbiddenFlags, listener);
|
||||
@ -852,11 +845,15 @@ public class MessagingController implements Runnable {
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(K9.LOG_TAG, "Could not complete remote search", e);
|
||||
if (listener != null) {
|
||||
listener.remoteSearchFailed(acct, null, e.getMessage());
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
Log.i(K9.LOG_TAG, "Caught exception on aborted remote search; safe to ignore.", e);
|
||||
} else {
|
||||
Log.e(K9.LOG_TAG, "Could not complete remote search", e);
|
||||
if (listener != null) {
|
||||
listener.remoteSearchFailed(acct, null, e.getMessage());
|
||||
}
|
||||
addErrorMessage(acct, null, e);
|
||||
}
|
||||
addErrorMessage(acct, null, e);
|
||||
} finally {
|
||||
if (listener != null) {
|
||||
listener.remoteSearchFinished(acct, folderName, 0, extraResults);
|
||||
|
@ -820,7 +820,7 @@ public class ImapStore extends Store {
|
||||
private volatile boolean mExists;
|
||||
private ImapStore store = null;
|
||||
Map<Long, String> msgSeqUidMap = new ConcurrentHashMap<Long, String>();
|
||||
|
||||
private boolean mInSearch = false;
|
||||
|
||||
public ImapFolder(ImapStore nStore, String name) {
|
||||
super(nStore.getAccount());
|
||||
@ -1000,7 +1000,13 @@ public class ImapStore extends Store {
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
releaseConnection(mConnection);
|
||||
// If we are mid-search and we get a close request, we gotta trash the connection.
|
||||
if (mInSearch && mConnection != null) {
|
||||
Log.i(K9.LOG_TAG, "IMAP search was aborted, shutting down connection.");
|
||||
mConnection.close();
|
||||
} else {
|
||||
releaseConnection(mConnection);
|
||||
}
|
||||
mConnection = null;
|
||||
}
|
||||
}
|
||||
@ -2307,11 +2313,11 @@ public class ImapStore extends Store {
|
||||
open(OpenMode.READ_ONLY);
|
||||
checkOpen();
|
||||
|
||||
//don't pass listener--we don't want to add messages until we've downloaded them
|
||||
mInSearch = true;
|
||||
// don't pass listener--we don't want to add messages until we've downloaded them
|
||||
return search(searcher, null);
|
||||
} catch (Exception e) {
|
||||
Log.e(K9.LOG_TAG, "Exception caught during remote search", e);
|
||||
throw new MessagingException("Error during search: " + e.toString());
|
||||
} finally {
|
||||
mInSearch = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user