Merge "Use the CursorWithExtras pattern for the message list."

This commit is contained in:
Makoto Onuki 2011-06-07 11:12:31 -07:00 committed by Android (Google) Code Review
commit cb530b4e91
4 changed files with 103 additions and 169 deletions

View File

@ -21,7 +21,6 @@ import com.android.email.Email;
import com.android.email.NotificationController;
import com.android.email.R;
import com.android.email.RefreshManager;
import com.android.email.data.MailboxAccountLoader;
import com.android.email.provider.EmailProvider;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.EmailContent.Account;
@ -92,8 +91,7 @@ public class MessageListFragment extends ListFragment
private static final String BUNDLE_KEY_SELECTED_MESSAGE_ID
= "messageListFragment.state.listState.selected_message_id";
private static final int LOADER_ID_MAILBOX_LOADER = 1;
private static final int LOADER_ID_MESSAGES_LOADER = 2;
private static final int LOADER_ID_MESSAGES_LOADER = 1;
/** Argument name(s) */
private static final String ARG_ACCOUNT_ID = "accountId";
@ -1149,48 +1147,7 @@ public class MessageListFragment extends ListFragment
// Start loading...
final LoaderManager lm = getLoaderManager();
lm.initLoader(LOADER_ID_MAILBOX_LOADER, null, new MailboxAccountLoaderCallback());
}
/**
* Loader callbacks for {@link MailboxAccountLoader}.
*/
private class MailboxAccountLoaderCallback implements LoaderManager.LoaderCallbacks<
MailboxAccountLoader.Result> {
@Override
public Loader<MailboxAccountLoader.Result> onCreateLoader(int id, Bundle args) {
final long mailboxId = getMailboxId();
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, MessageListFragment.this
+ " onCreateLoader(mailbox) mailboxId=" + mailboxId);
}
return new MailboxAccountLoader(getActivity().getApplicationContext(), mailboxId);
}
@Override
public void onLoadFinished(Loader<MailboxAccountLoader.Result> loader,
MailboxAccountLoader.Result result) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, MessageListFragment.this
+ " onLoadFinished(mailbox) mailboxId=" + getMailboxId());
}
if (!result.mIsFound) {
mCallback.onMailboxNotFound();
return;
}
mAccount = result.mAccount;
mMailbox = result.mMailbox;
mIsEasAccount = result.mIsEasAccount;
mIsRefreshable = result.mIsRefreshable;
mCountTotalAccounts = result.mCountTotalAccounts;
getLoaderManager().initLoader(LOADER_ID_MESSAGES_LOADER, null,
new MessagesLoaderCallback());
}
@Override
public void onLoaderReset(Loader<MailboxAccountLoader.Result> loader) {
}
lm.initLoader(LOADER_ID_MESSAGES_LOADER, null, new MessagesLoaderCallback());
}
/**
@ -1211,11 +1168,25 @@ public class MessageListFragment extends ListFragment
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, MessageListFragment.this
+ " onLoadFinished(messages) mailboxId=" + getMailboxId());
}
MessagesAdapter.CursorWithExtras cursor =
(MessagesAdapter.CursorWithExtras) c;
if (!cursor.mIsFound) {
mCallback.onMailboxNotFound();
return;
}
// Get the "extras" part.
mAccount = cursor.mAccount;
mMailbox = cursor.mMailbox;
mIsEasAccount = cursor.mIsEasAccount;
mIsRefreshable = cursor.mIsRefreshable;
mCountTotalAccounts = cursor.mCountTotalAccounts;
// Suspend message notifications as long as we're resumed
adjustMessageNotification(false);

View File

@ -21,6 +21,7 @@ import com.android.email.ResourceHelper;
import com.android.email.data.ThrottlingCursorLoader;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.provider.EmailContent.MessageColumns;
import com.android.emailcommon.provider.Mailbox;
@ -30,6 +31,7 @@ import com.android.emailcommon.utility.Utility;
import android.content.Context;
import android.content.Loader;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.MatrixCursor;
import android.os.Bundle;
import android.util.Log;
@ -93,6 +95,36 @@ import java.util.Set;
private final Callback mCallback;
/**
* The actual return type from the loader.
*/
public static class CursorWithExtras extends CursorWrapper {
/** Whether the mailbox is found. */
public final boolean mIsFound;
/** {@link Account} that owns the mailbox. Null for combined mailboxes. */
public final Account mAccount;
/** {@link Mailbox} for the loaded mailbox. Null for combined mailboxes. */
public final Mailbox mMailbox;
/** {@code true} if the account is an EAS account */
public final boolean mIsEasAccount;
/** {@code true} if the loaded mailbox can be refreshed. */
public final boolean mIsRefreshable;
/** the number of accounts currently configured. */
public final int mCountTotalAccounts;
private CursorWithExtras(Cursor cursor,
boolean found, Account account, Mailbox mailbox, boolean isEasAccount,
boolean isRefreshable, int countTotalAccounts) {
super(cursor);
mIsFound = found;
mAccount = account;
mMailbox = mailbox;
mIsEasAccount = isEasAccount;
mIsRefreshable = isRefreshable;
mCountTotalAccounts = countTotalAccounts;
}
}
public MessagesAdapter(Context context, Callback callback) {
super(context.getApplicationContext(), null, 0 /* no auto requery */);
mResourceHelper = ResourceHelper.getInstance(context);
@ -222,6 +254,11 @@ import java.util.Set;
view.invalidate();
}
/**
* Creates the loader for {@link MessageListFragment}.
*
* @return always of {@link CursorWithExtras}.
*/
public static Loader<Cursor> createLoader(Context context, long mailboxId) {
if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) {
Log.d(Logging.LOG_TAG, "MessagesAdapter createLoader mailboxId=" + mailboxId);
@ -266,7 +303,35 @@ import java.util.Set;
// return an empty cursor
returnCursor = new MatrixCursor(getProjection());
}
return Utility.CloseTraceCursorWrapper.get(returnCursor);
return loadExtras(returnCursor);
}
private Cursor loadExtras(Cursor baseCursor) {
boolean found = false;
Account account = null;
Mailbox mailbox = null;
boolean isEasAccount = false;
boolean isRefreshable = false;
if (mMailboxId < 0) {
// Magic mailbox.
found = true;
} else {
mailbox = Mailbox.restoreMailboxWithId(mContext, mMailboxId);
if (mailbox != null) {
account = Account.restoreAccountWithId(mContext, mailbox.mAccountKey);
if (account != null) {
found = true;
isEasAccount = account.isEasAccount(mContext) ;
isRefreshable = Mailbox.isRefreshable(mContext, mMailboxId);
} else { // Account removed?
mailbox = null;
}
}
}
final int countAccounts = EmailContent.count(mContext, Account.CONTENT_URI);
return new CursorWithExtras(baseCursor, found, account, mailbox, isEasAccount,
isRefreshable, countAccounts);
}
}
}

View File

@ -1,107 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.email.data;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.Mailbox;
import android.content.AsyncTaskLoader;
import android.content.Context;
/**
* Loader to load {@link Mailbox} and {@link Account}.
*/
public class MailboxAccountLoader extends AsyncTaskLoader<MailboxAccountLoader.Result> {
public static class Result {
public final boolean mIsFound;
public final Account mAccount;
public final Mailbox mMailbox;
public final boolean mIsEasAccount;
public final boolean mIsRefreshable;
public final int mCountTotalAccounts;
private Result(boolean found, Account account, Mailbox mailbox, boolean isEasAccount,
boolean isRefreshable, int countTotalAccounts) {
mIsFound = found;
mAccount = account;
mMailbox = mailbox;
mIsEasAccount = isEasAccount;
mIsRefreshable = isRefreshable;
mCountTotalAccounts = countTotalAccounts;
}
}
private final Context mContext;
private final long mMailboxId;
public MailboxAccountLoader(Context context, long mailboxId) {
super(context);
if (mailboxId == -1) {
throw new IllegalArgumentException();
}
mContext = context;
mMailboxId = mailboxId;
}
@Override
public Result loadInBackground() {
boolean found = false;
Account account = null;
Mailbox mailbox = null;
boolean isEasAccount = false;
boolean isRefreshable = false;
if (mMailboxId < 0) {
// Magic mailbox.
found = true;
} else {
mailbox = Mailbox.restoreMailboxWithId(mContext, mMailboxId);
if (mailbox != null) {
account = Account.restoreAccountWithId(mContext, mailbox.mAccountKey);
if (account != null) {
found = true;
isEasAccount = account.isEasAccount(mContext) ;
isRefreshable = Mailbox.isRefreshable(mContext, mMailboxId);
} else { // Account removed?
mailbox = null;
}
}
}
final int countAccounts = EmailContent.count(mContext, Account.CONTENT_URI);
Result result = new Result(found, account, mailbox, isEasAccount, isRefreshable,
countAccounts);
return result;
}
@Override
protected void onStartLoading() {
cancelLoad();
forceLoad();
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
protected void onReset() {
stopLoading();
}
}

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.email.data;
package com.android.email.activity;
import com.android.email.DBTestHelper;
import com.android.email.provider.ProviderTestUtils;
@ -24,7 +24,13 @@ import com.android.emailcommon.provider.Mailbox;
import android.content.Context;
import android.test.LoaderTestCase;
public class MailboxAccountLoaderTestCase extends LoaderTestCase {
public class MessagesAdapterTests extends LoaderTestCase {
// Account ID that's probably not in the database.
private static final long NO_SUCH_ACCOUNT_ID = 1234567890123L;
// Mailbox ID that's probably not in the database.
private static final long NO_SUCH_MAILBOX_ID = 1234567890123L;
// Isolated Context for providers.
private Context mProviderContext;
@ -50,6 +56,11 @@ public class MailboxAccountLoaderTestCase extends LoaderTestCase {
return box.mId;
}
private MessagesAdapter.CursorWithExtras getLoaderResult(long mailboxId) {
return (MessagesAdapter.CursorWithExtras) getLoaderResultSynchronously(
MessagesAdapter.createLoader(mProviderContext, mailboxId));
}
/**
* Test for normal case. (account, mailbox found)
*/
@ -57,8 +68,7 @@ public class MailboxAccountLoaderTestCase extends LoaderTestCase {
final long accountId = createAccount(false);
final long mailboxId = createMailbox(accountId, Mailbox.TYPE_MAIL);
MailboxAccountLoader.Result result = getLoaderResultSynchronously(
new MailboxAccountLoader(mProviderContext, mailboxId));
MessagesAdapter.CursorWithExtras result = getLoaderResult(mailboxId);
assertTrue(result.mIsFound);
assertEquals(accountId, result.mAccount.mId);
assertEquals(mailboxId, result.mMailbox.mId);
@ -73,8 +83,7 @@ public class MailboxAccountLoaderTestCase extends LoaderTestCase {
final long accountId = createAccount(true);
final long mailboxId = createMailbox(accountId, Mailbox.TYPE_MAIL);
MailboxAccountLoader.Result result = getLoaderResultSynchronously(
new MailboxAccountLoader(mProviderContext, mailboxId));
MessagesAdapter.CursorWithExtras result = getLoaderResult(mailboxId);
assertTrue(result.mIsFound);
assertEquals(accountId, result.mAccount.mId);
assertEquals(mailboxId, result.mMailbox.mId);
@ -89,8 +98,7 @@ public class MailboxAccountLoaderTestCase extends LoaderTestCase {
final long accountId = createAccount(false);
final long mailboxId = createMailbox(accountId, Mailbox.TYPE_DRAFTS);
MailboxAccountLoader.Result result = getLoaderResultSynchronously(
new MailboxAccountLoader(mProviderContext, mailboxId));
MessagesAdapter.CursorWithExtras result = getLoaderResult(mailboxId);
assertTrue(result.mIsFound);
assertEquals(accountId, result.mAccount.mId);
assertEquals(mailboxId, result.mMailbox.mId);
@ -102,8 +110,7 @@ public class MailboxAccountLoaderTestCase extends LoaderTestCase {
* Mailbox not found.
*/
public void testMailboxNotFound() {
MailboxAccountLoader.Result result = getLoaderResultSynchronously(
new MailboxAccountLoader(mProviderContext, 123));
MessagesAdapter.CursorWithExtras result = getLoaderResult(NO_SUCH_MAILBOX_ID);
assertFalse(result.mIsFound);
assertNull(result.mAccount);
assertNull(result.mMailbox);
@ -115,10 +122,9 @@ public class MailboxAccountLoaderTestCase extends LoaderTestCase {
* Account not found.
*/
public void testAccountNotFound() {
final long mailboxId = createMailbox(1, Mailbox.TYPE_MAIL);
final long mailboxId = createMailbox(NO_SUCH_ACCOUNT_ID, Mailbox.TYPE_MAIL);
MailboxAccountLoader.Result result = getLoaderResultSynchronously(
new MailboxAccountLoader(mProviderContext, mailboxId));
MessagesAdapter.CursorWithExtras result = getLoaderResult(mailboxId);
assertFalse(result.mIsFound);
assertNull(result.mAccount);
assertNull(result.mMailbox);
@ -130,8 +136,7 @@ public class MailboxAccountLoaderTestCase extends LoaderTestCase {
* Magic mailbox. (always found)
*/
public void testMagicMailbox() {
MailboxAccountLoader.Result result = getLoaderResultSynchronously(
new MailboxAccountLoader(mProviderContext, Mailbox.QUERY_ALL_INBOXES));
MessagesAdapter.CursorWithExtras result = getLoaderResult(Mailbox.QUERY_ALL_INBOXES);
assertTrue(result.mIsFound);
assertNull(result.mAccount);
assertNull(result.mMailbox);