From 37c8a70d644ffc91a880f67a80a8558b4c53d5c3 Mon Sep 17 00:00:00 2001 From: Ben Komalo Date: Mon, 27 Jun 2011 15:20:58 -0700 Subject: [PATCH] Introduce a SearchCursorLoader This loader will abstract away the waiting for the controller to cleanup the existing contents of the search mailbox After some additional, to-be-done plumbing, I'd like Controller.searchMessages to return some results info (like # of results at the least) so that the SearchCursor returned can relay that information to the client (which can then do a lot more interesting things at that point). Change-Id: Ifcba0ddf7170c56dac9f3b44128988a5aa4ca887 --- .../android/email/activity/EmailActivity.java | 15 ---- .../email/activity/MessageListFragment.java | 17 ++-- .../email/activity/MessagesAdapter.java | 78 ++++++++++++++----- .../email/activity/MessagesAdapterTests.java | 21 +++-- 4 files changed, 83 insertions(+), 48 deletions(-) diff --git a/src/com/android/email/activity/EmailActivity.java b/src/com/android/email/activity/EmailActivity.java index 7c697f105..1d31d06e3 100644 --- a/src/com/android/email/activity/EmailActivity.java +++ b/src/com/android/email/activity/EmailActivity.java @@ -208,21 +208,6 @@ public class EmailActivity extends Activity implements View.OnClickListener, Fra final MessageListContext viewContext = MessageListContext.forIntent(this, intent); final long messageId = intent.getLongExtra(EXTRA_MESSAGE_ID, Message.NO_MESSAGE); - if (viewContext.isSearch()) { - EmailAsyncTask.runAsyncParallel(new Runnable() { - @Override - public void run() { - try { - Controller controller = Controller.getInstance(EmailActivity.this); - controller.searchMessages( - viewContext.mAccountId, viewContext.getSearchParams()); - } catch (MessagingException e) { - // TODO: handle. - Log.e(Logging.LOG_TAG, "Got exception while searching " + e); - } - }}); - } - mUIController.open(viewContext, messageId); } diff --git a/src/com/android/email/activity/MessageListFragment.java b/src/com/android/email/activity/MessageListFragment.java index 999fcc563..b690cc88a 100644 --- a/src/com/android/email/activity/MessageListFragment.java +++ b/src/com/android/email/activity/MessageListFragment.java @@ -288,6 +288,11 @@ public class MessageListFragment extends ListFragment return getMailboxId() < 0; } + public MessageListContext getListContext() { + initializeArgCache(); + return mListContext; + } + @Override public void onAttach(Activity activity) { if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { @@ -1033,7 +1038,6 @@ public class MessageListFragment extends ListFragment } determineFooterMode(); if (mListFooterMode != LIST_FOOTER_MODE_NONE) { - lv.addFooterView(mListFooterView); lv.setAdapter(mListAdapter); @@ -1134,13 +1138,13 @@ public class MessageListFragment extends ListFragment @Override public Loader onCreateLoader(int id, Bundle args) { - final long mailboxId = getMailboxId(); + final MessageListContext listContext = getListContext(); if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { Log.d(Logging.LOG_TAG, MessageListFragment.this - + " onCreateLoader(messages) mailboxId=" + mailboxId); + + " onCreateLoader(messages) listContext=" + listContext); } mIsFirstLoad = true; - return MessagesAdapter.createLoader(getActivity(), mailboxId); + return MessagesAdapter.createLoader(getActivity(), listContext); } @Override @@ -1149,8 +1153,7 @@ public class MessageListFragment extends ListFragment Log.d(Logging.LOG_TAG, MessageListFragment.this + " onLoadFinished(messages) mailboxId=" + getMailboxId()); } - MessagesAdapter.CursorWithExtras cursor = - (MessagesAdapter.CursorWithExtras) c; + MessagesAdapter.CursorWithExtras cursor = (MessagesAdapter.CursorWithExtras) c; if (!cursor.mIsFound) { mCallback.onMailboxNotFound(); @@ -1195,7 +1198,7 @@ public class MessageListFragment extends ListFragment updateSelectionMode(); showSendCommandIfNecessary(); showNoMessageText((cursor.getCount() == 0) - && (mListFooterMode == LIST_FOOTER_MODE_NONE)); + && (getListContext().isSearch() || (mListFooterMode == LIST_FOOTER_MODE_NONE))); // We want to make visible the selection only for the first load. // Re-load caused by content changed events shouldn't scroll the list. diff --git a/src/com/android/email/activity/MessagesAdapter.java b/src/com/android/email/activity/MessagesAdapter.java index 2299d4ed4..5c9606b49 100644 --- a/src/com/android/email/activity/MessagesAdapter.java +++ b/src/com/android/email/activity/MessagesAdapter.java @@ -16,18 +16,6 @@ package com.android.email.activity; -import com.android.email.Email; -import com.android.email.ResourceHelper; -import com.android.email.data.ThrottlingCursorLoader; -import com.android.emailcommon.Logging; -import com.android.emailcommon.provider.Account; -import com.android.emailcommon.provider.EmailContent; -import com.android.emailcommon.provider.EmailContent.Message; -import com.android.emailcommon.provider.EmailContent.MessageColumns; -import com.android.emailcommon.provider.Mailbox; -import com.android.emailcommon.utility.TextUtilities; -import com.android.emailcommon.utility.Utility; - import android.content.Context; import android.content.Loader; import android.database.Cursor; @@ -39,6 +27,22 @@ import android.view.View; import android.view.ViewGroup; import android.widget.CursorAdapter; +import com.android.email.Controller; +import com.android.email.Email; +import com.android.email.MessageListContext; +import com.android.email.ResourceHelper; +import com.android.email.data.ThrottlingCursorLoader; +import com.android.emailcommon.Logging; +import com.android.emailcommon.mail.MessagingException; +import com.android.emailcommon.provider.Account; +import com.android.emailcommon.provider.EmailContent; +import com.android.emailcommon.provider.EmailContent.Message; +import com.android.emailcommon.provider.EmailContent.MessageColumns; +import com.android.emailcommon.provider.Mailbox; +import com.android.emailcommon.utility.TextUtilities; +import com.android.emailcommon.utility.Utility; +import com.google.common.base.Preconditions; + import java.util.HashSet; import java.util.Set; @@ -259,16 +263,17 @@ import java.util.Set; * * @return always of {@link CursorWithExtras}. */ - public static Loader createLoader(Context context, long mailboxId) { + public static Loader createLoader(Context context, MessageListContext listContext) { if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { - Log.d(Logging.LOG_TAG, "MessagesAdapter createLoader mailboxId=" + mailboxId); + Log.d(Logging.LOG_TAG, "MessagesAdapter createLoader listContext=" + listContext); } - return new MessagesCursorLoader(context, mailboxId); - + return listContext.isSearch() + ? new SearchCursorLoader(context, listContext) + : new MessagesCursorLoader(context, listContext.getMailboxId()); } - static private class MessagesCursorLoader extends ThrottlingCursorLoader { - private final Context mContext; + private static class MessagesCursorLoader extends ThrottlingCursorLoader { + protected final Context mContext; private final long mMailboxId; public MessagesCursorLoader(Context context, long mailboxId) { @@ -334,4 +339,41 @@ import java.util.Set; isRefreshable, countAccounts); } } + + /** + * A special loader used to perform a search. + */ + private static class SearchCursorLoader extends MessagesCursorLoader { + private final MessageListContext mListContext; + private boolean mResultCountAvailable = false; + + public SearchCursorLoader(Context context, MessageListContext listContext) { + super(context, listContext.getMailboxId()); + Preconditions.checkArgument(listContext.isSearch()); + mListContext = listContext; + } + + @Override + public Cursor loadInBackground() { + if (mResultCountAvailable) { + return super.loadInBackground(); + } + + // The search results info hasn't even been loaded yet, so the Controller has not yet + // initialized the search mailbox properly. Kick off the search first. + Controller controller = Controller.getInstance(mContext); + try { + // TODO: wire through search count information and pad it into the cursor returned + // so that the caller knows how many is in the entire result set. + controller.searchMessages(mListContext.mAccountId, mListContext.getSearchParams()); + } catch (MessagingException e) { + // TODO: handle. + } + + mResultCountAvailable = true; + + // Return whatever the super would do, now that we know the results are ready. + return super.loadInBackground(); + } + } } diff --git a/tests/src/com/android/email/activity/MessagesAdapterTests.java b/tests/src/com/android/email/activity/MessagesAdapterTests.java index 243230a72..af870322a 100644 --- a/tests/src/com/android/email/activity/MessagesAdapterTests.java +++ b/tests/src/com/android/email/activity/MessagesAdapterTests.java @@ -17,6 +17,7 @@ package com.android.email.activity; import com.android.email.DBTestHelper; +import com.android.email.MessageListContext; import com.android.email.provider.ProviderTestUtils; import com.android.emailcommon.provider.Account; import com.android.emailcommon.provider.Mailbox; @@ -56,9 +57,11 @@ public class MessagesAdapterTests extends LoaderTestCase { return box.mId; } - private MessagesAdapter.CursorWithExtras getLoaderResult(long mailboxId) { + private MessagesAdapter.CursorWithExtras getLoaderResult(long accountId, long mailboxId) { return (MessagesAdapter.CursorWithExtras) getLoaderResultSynchronously( - MessagesAdapter.createLoader(mProviderContext, mailboxId)); + MessagesAdapter.createLoader( + mProviderContext, + MessageListContext.forMailbox(accountId, mailboxId))); } /** @@ -68,7 +71,7 @@ public class MessagesAdapterTests extends LoaderTestCase { final long accountId = createAccount(false); final long mailboxId = createMailbox(accountId, Mailbox.TYPE_MAIL); - MessagesAdapter.CursorWithExtras result = getLoaderResult(mailboxId); + MessagesAdapter.CursorWithExtras result = getLoaderResult(accountId, mailboxId); assertTrue(result.mIsFound); assertEquals(accountId, result.mAccount.mId); assertEquals(mailboxId, result.mMailbox.mId); @@ -83,7 +86,7 @@ public class MessagesAdapterTests extends LoaderTestCase { final long accountId = createAccount(true); final long mailboxId = createMailbox(accountId, Mailbox.TYPE_MAIL); - MessagesAdapter.CursorWithExtras result = getLoaderResult(mailboxId); + MessagesAdapter.CursorWithExtras result = getLoaderResult(accountId, mailboxId); assertTrue(result.mIsFound); assertEquals(accountId, result.mAccount.mId); assertEquals(mailboxId, result.mMailbox.mId); @@ -98,7 +101,7 @@ public class MessagesAdapterTests extends LoaderTestCase { final long accountId = createAccount(false); final long mailboxId = createMailbox(accountId, Mailbox.TYPE_DRAFTS); - MessagesAdapter.CursorWithExtras result = getLoaderResult(mailboxId); + MessagesAdapter.CursorWithExtras result = getLoaderResult(accountId, mailboxId); assertTrue(result.mIsFound); assertEquals(accountId, result.mAccount.mId); assertEquals(mailboxId, result.mMailbox.mId); @@ -110,7 +113,8 @@ public class MessagesAdapterTests extends LoaderTestCase { * Mailbox not found. */ public void testMailboxNotFound() { - MessagesAdapter.CursorWithExtras result = getLoaderResult(NO_SUCH_MAILBOX_ID); + MessagesAdapter.CursorWithExtras result = getLoaderResult( + createAccount(false), NO_SUCH_MAILBOX_ID); assertFalse(result.mIsFound); assertNull(result.mAccount); assertNull(result.mMailbox); @@ -124,7 +128,7 @@ public class MessagesAdapterTests extends LoaderTestCase { public void testAccountNotFound() { final long mailboxId = createMailbox(NO_SUCH_ACCOUNT_ID, Mailbox.TYPE_MAIL); - MessagesAdapter.CursorWithExtras result = getLoaderResult(mailboxId); + MessagesAdapter.CursorWithExtras result = getLoaderResult(NO_SUCH_ACCOUNT_ID, mailboxId); assertFalse(result.mIsFound); assertNull(result.mAccount); assertNull(result.mMailbox); @@ -136,7 +140,8 @@ public class MessagesAdapterTests extends LoaderTestCase { * Magic mailbox. (always found) */ public void testMagicMailbox() { - MessagesAdapter.CursorWithExtras result = getLoaderResult(Mailbox.QUERY_ALL_INBOXES); + MessagesAdapter.CursorWithExtras result = getLoaderResult( + Account.ACCOUNT_ID_COMBINED_VIEW, Mailbox.QUERY_ALL_INBOXES); assertTrue(result.mIsFound); assertNull(result.mAccount); assertNull(result.mMailbox);