Merge pull request #2203 from philipwhiuk/clearFolderNotOnUiThread
Clear folder using the MessagingController instead of on the UI thread
This commit is contained in:
commit
8ee9b2c591
3 changed files with 98 additions and 24 deletions
|
@ -476,31 +476,9 @@ public class FolderList extends K9ListActivity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onClearFolder(Account account, String folderName) {
|
private void onClearFolder(Account account, String folderName) {
|
||||||
// There has to be a cheaper way to get at the localFolder object than this
|
MessagingController.getInstance(getApplication()).clearFolder(account, folderName, mAdapter.mListener);
|
||||||
LocalFolder localFolder = null;
|
|
||||||
try {
|
|
||||||
if (account == null || folderName == null || !account.isAvailable(FolderList.this)) {
|
|
||||||
Log.i(K9.LOG_TAG, "not clear folder of unavailable account");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
localFolder = account.getLocalStore().getFolder(folderName);
|
|
||||||
localFolder.open(Folder.OPEN_MODE_RW);
|
|
||||||
localFolder.clearAllMessages();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(K9.LOG_TAG, "Exception while clearing folder", e);
|
|
||||||
} finally {
|
|
||||||
if (localFolder != null) {
|
|
||||||
localFolder.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onRefresh(!REFRESH_REMOTE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void sendMail(Account account) {
|
private void sendMail(Account account) {
|
||||||
MessagingController.getInstance(getApplication()).sendPendingMessages(account, mAdapter.mListener);
|
MessagingController.getInstance(getApplication()).sendPendingMessages(account, mAdapter.mListener);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.K9.Intents;
|
import com.fsck.k9.K9.Intents;
|
||||||
import com.fsck.k9.Preferences;
|
import com.fsck.k9.Preferences;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.activity.ActivityListener;
|
||||||
import com.fsck.k9.activity.MessageReference;
|
import com.fsck.k9.activity.MessageReference;
|
||||||
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
|
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
|
||||||
import com.fsck.k9.cache.EmailProviderCache;
|
import com.fsck.k9.cache.EmailProviderCache;
|
||||||
|
@ -3513,6 +3514,36 @@ public class MessagingController {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearFolder(final Account account, final String folderName, final ActivityListener listener) {
|
||||||
|
putBackground("clearFolder", listener, new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
clearFolderSynchronous(account, folderName, listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected void clearFolderSynchronous(Account account, String folderName, MessagingListener listener) {
|
||||||
|
LocalFolder localFolder = null;
|
||||||
|
try {
|
||||||
|
localFolder = account.getLocalStore().getFolder(folderName);
|
||||||
|
localFolder.open(Folder.OPEN_MODE_RW);
|
||||||
|
localFolder.clearAllMessages();
|
||||||
|
} catch (UnavailableStorageException e) {
|
||||||
|
Log.i(K9.LOG_TAG, "Failed to clear folder because storage is not available - trying again later.");
|
||||||
|
throw new UnavailableAccountException(e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(K9.LOG_TAG, "clearFolder failed", e);
|
||||||
|
addErrorMessage(account, null, e);
|
||||||
|
} finally {
|
||||||
|
closeFolder(localFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
listFoldersSynchronous(account, false, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find out whether the account type only supports a local Trash folder.
|
* Find out whether the account type only supports a local Trash folder.
|
||||||
*
|
*
|
||||||
|
|
|
@ -13,6 +13,7 @@ import android.content.Context;
|
||||||
|
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.AccountStats;
|
import com.fsck.k9.AccountStats;
|
||||||
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.K9RobolectricTestRunner;
|
import com.fsck.k9.K9RobolectricTestRunner;
|
||||||
import com.fsck.k9.Preferences;
|
import com.fsck.k9.Preferences;
|
||||||
import com.fsck.k9.helper.Contacts;
|
import com.fsck.k9.helper.Contacts;
|
||||||
|
@ -26,6 +27,7 @@ import com.fsck.k9.mail.Store;
|
||||||
import com.fsck.k9.mailstore.LocalFolder;
|
import com.fsck.k9.mailstore.LocalFolder;
|
||||||
import com.fsck.k9.mailstore.LocalMessage;
|
import com.fsck.k9.mailstore.LocalMessage;
|
||||||
import com.fsck.k9.mailstore.LocalStore;
|
import com.fsck.k9.mailstore.LocalStore;
|
||||||
|
import com.fsck.k9.mailstore.UnavailableStorageException;
|
||||||
import com.fsck.k9.notification.NotificationController;
|
import com.fsck.k9.notification.NotificationController;
|
||||||
import com.fsck.k9.search.LocalSearch;
|
import com.fsck.k9.search.LocalSearch;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
@ -51,6 +53,7 @@ import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.atLeast;
|
import static org.mockito.Mockito.atLeast;
|
||||||
import static org.mockito.Mockito.atLeastOnce;
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
|
@ -80,6 +83,8 @@ public class MessagingControllerTest {
|
||||||
@Mock
|
@Mock
|
||||||
private LocalFolder localFolder;
|
private LocalFolder localFolder;
|
||||||
@Mock
|
@Mock
|
||||||
|
private LocalFolder errorFolder;
|
||||||
|
@Mock
|
||||||
private Folder remoteFolder;
|
private Folder remoteFolder;
|
||||||
@Mock
|
@Mock
|
||||||
private LocalStore localStore;
|
private LocalStore localStore;
|
||||||
|
@ -130,6 +135,62 @@ public class MessagingControllerTest {
|
||||||
controller.stop();
|
controller.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clearFolderSynchronous_shouldOpenFolderForWriting() throws MessagingException {
|
||||||
|
controller.clearFolderSynchronous(account, FOLDER_NAME, listener);
|
||||||
|
|
||||||
|
verify(localFolder).open(Folder.OPEN_MODE_RW);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clearFolderSynchronous_shouldClearAllMessagesInTheFolder() throws MessagingException {
|
||||||
|
controller.clearFolderSynchronous(account, FOLDER_NAME, listener);
|
||||||
|
|
||||||
|
verify(localFolder).clearAllMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clearFolderSynchronous_shouldCloseTheFolder() throws MessagingException {
|
||||||
|
controller.clearFolderSynchronous(account, FOLDER_NAME, listener);
|
||||||
|
|
||||||
|
verify(localFolder, atLeastOnce()).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = UnavailableAccountException.class)
|
||||||
|
public void clearFolderSynchronous_whenStorageUnavailable_shouldThrowUnavailableAccountException() throws MessagingException {
|
||||||
|
doThrow(new UnavailableStorageException("Test")).when(localFolder).open(Folder.OPEN_MODE_RW);
|
||||||
|
|
||||||
|
controller.clearFolderSynchronous(account, FOLDER_NAME, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
public void clearFolderSynchronous_whenExceptionThrown_shouldAddErrorMessage() throws MessagingException {
|
||||||
|
doThrow(new RuntimeException("Test")).when(localFolder).open(Folder.OPEN_MODE_RW);
|
||||||
|
|
||||||
|
controller.clearFolderSynchronous(account, FOLDER_NAME, listener);
|
||||||
|
|
||||||
|
verify(errorFolder).appendMessages(any(List.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
public void clearFolderSynchronous_whenExceptionThrown_shouldStillCloseFolder() throws MessagingException {
|
||||||
|
doThrow(new RuntimeException("Test")).when(localFolder).open(Folder.OPEN_MODE_RW);
|
||||||
|
|
||||||
|
try {
|
||||||
|
controller.clearFolderSynchronous(account, FOLDER_NAME, listener);
|
||||||
|
} catch (Exception ignored){
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(localFolder, atLeastOnce()).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test()
|
||||||
|
public void clearFolderSynchronous_shouldListFolders() throws MessagingException {
|
||||||
|
controller.clearFolderSynchronous(account, FOLDER_NAME, listener);
|
||||||
|
|
||||||
|
verify(listener, atLeastOnce()).listFoldersStarted(account);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void listFoldersSynchronous_shouldNotifyTheListenerListingStarted() throws MessagingException {
|
public void listFoldersSynchronous_shouldNotifyTheListenerListingStarted() throws MessagingException {
|
||||||
List<LocalFolder> folders = Collections.singletonList(localFolder);
|
List<LocalFolder> folders = Collections.singletonList(localFolder);
|
||||||
|
@ -758,11 +819,15 @@ public class MessagingControllerTest {
|
||||||
when(account.getLocalStore()).thenReturn(localStore);
|
when(account.getLocalStore()).thenReturn(localStore);
|
||||||
when(account.getStats(any(Context.class))).thenReturn(accountStats);
|
when(account.getStats(any(Context.class))).thenReturn(accountStats);
|
||||||
when(account.getMaximumAutoDownloadMessageSize()).thenReturn(MAXIMUM_SMALL_MESSAGE_SIZE);
|
when(account.getMaximumAutoDownloadMessageSize()).thenReturn(MAXIMUM_SMALL_MESSAGE_SIZE);
|
||||||
|
when(account.getErrorFolderName()).thenReturn(K9.ERROR_FOLDER_NAME);
|
||||||
|
when(account.getEmail()).thenReturn("user@host.com");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureLocalStore() {
|
private void configureLocalStore() throws MessagingException {
|
||||||
when(localStore.getFolder(FOLDER_NAME)).thenReturn(localFolder);
|
when(localStore.getFolder(FOLDER_NAME)).thenReturn(localFolder);
|
||||||
when(localFolder.getName()).thenReturn(FOLDER_NAME);
|
when(localFolder.getName()).thenReturn(FOLDER_NAME);
|
||||||
|
when(localStore.getFolder(K9.ERROR_FOLDER_NAME)).thenReturn(errorFolder);
|
||||||
|
when(localStore.getPersonalNamespaces(false)).thenReturn(Collections.singletonList(localFolder));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureRemoteStoreWithFolder() throws MessagingException {
|
private void configureRemoteStoreWithFolder() throws MessagingException {
|
||||||
|
|
Loading…
Reference in a new issue