Merge "Introduce a SearchCursorLoader"

This commit is contained in:
Ben Komalo 2011-06-27 17:32:25 -07:00 committed by Android (Google) Code Review
commit f8acc29628
4 changed files with 83 additions and 48 deletions

View File

@ -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);
}

View File

@ -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<Cursor> 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.

View File

@ -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<Cursor> createLoader(Context context, long mailboxId) {
public static Loader<Cursor> 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();
}
}
}

View File

@ -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);