From 80d3875d306c60da83e547c573427627911f8a99 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Thu, 23 Jun 2011 14:04:53 -0700 Subject: [PATCH] Action bar: Use laoder to get current mailbox info Before this CL, we had this crazy plumbing from MailboxListFragment to ActionBarController to update the current mailbox name/message count. This wouldn't work on 1-pane, so now ABC just gets the current mailbox id from UIC and loads the name/count with its own loader. Also... - Fixed bug 4904450 and bug 4460470: Now we consistently use FolderProperties to get proler display names and message counts. - Renamed some confusing names in AccountSelectorAdapter Change-Id: Ic7bea6da6d2859006fb8f9263024c7d5e62b1e7f --- src/com/android/email/FolderProperties.java | 86 +++++++-- .../activity/AccountSelectorAdapter.java | 114 +++++++---- .../email/activity/ActionBarController.java | 86 +++++++-- .../activity/MailboxFragmentAdapter.java | 82 ++------ .../email/activity/MailboxListFragment.java | 28 +-- .../email/activity/MailboxMoveToAdapter.java | 7 +- .../email/activity/UIControllerOnePane.java | 19 +- .../email/activity/UIControllerTwoPane.java | 36 +--- .../android/email/FolderPropertiesTests.java | 181 ++++++++++++++++++ ...ountSelectorAdapterAccountsLoaderTest.java | 8 +- .../emailcommon/utility/UtilityUnitTests.java | 66 ------- 11 files changed, 432 insertions(+), 281 deletions(-) create mode 100644 tests/src/com/android/email/FolderPropertiesTests.java diff --git a/src/com/android/email/FolderProperties.java b/src/com/android/email/FolderProperties.java index 7fb4264cd..9b95404f7 100644 --- a/src/com/android/email/FolderProperties.java +++ b/src/com/android/email/FolderProperties.java @@ -16,21 +16,24 @@ package com.android.email; +import com.android.emailcommon.provider.EmailContent.MailboxColumns; import com.android.emailcommon.provider.Mailbox; import android.content.Context; import android.content.res.TypedArray; +import android.database.Cursor; import android.graphics.drawable.Drawable; // TODO When the UI is settled, cache all strings/drawables -// TODO When the UI is settled, write up tests -// TODO When the UI is settled, remove backward-compatibility methods /** * Stores names and icons for system folders. System folders are those with special * meaning, such as Inbox, Drafts, Trash, etc... Although these folders may or may * not exist on the server, we want to ensure they are displayed in a very specific * manner. + * + * Some methods probably should belong to {@link Mailbox}, but as this class uses resources, + * we can't move them to emailcommon... */ public class FolderProperties { @@ -68,20 +71,10 @@ public class FolderProperties { return sInstance; } - // For backward compatibility. - public String getDisplayName(int type) { - return getDisplayName(type, -1); - } - - // For backward compatibility. - public Drawable getSummaryMailboxIconIds(long id) { - return getIcon(-1, id, 0); - } - /** * Lookup names of localized special mailboxes */ - public String getDisplayName(int type, long mailboxId) { + private String getDisplayName(int type, long mailboxId) { // Special combined mailboxes int resId = 0; @@ -105,6 +98,73 @@ public class FolderProperties { return null; } + /** + * Return the display name for a mailbox for UI. For normal mailboxes, it just returns + * {@code originalDisplayName}, but for special mailboxes (such as combined mailboxes) it + * returns a name obtained from the resource. + * + * @param mailboxType Such as {@link Mailbox#TYPE_INBOX} + * @param mailboxId ID of a mailbox. + * @param originalDisplayName Display name of the mailbox stored in the database. + */ + public String getDisplayName(int mailboxType, long mailboxId, String originalDisplayName) { + String name = getDisplayName(mailboxType, mailboxId); + if (name != null) { + return name; + } + return originalDisplayName; + } + + /** + * Same as {@link #getDisplayName(int, long, String)}, but gets information form a mailbox + * cursor. The cursor must contain the following columns: + * {@link MailboxColumns#ID}, {@link MailboxColumns#TYPE} and + * {@link MailboxColumns#DISPLAY_NAME}. + */ + public String getDisplayName(Cursor mailboxCursor) { + final Cursor c = mailboxCursor; + return getDisplayName( + c.getInt(c.getColumnIndex(MailboxColumns.TYPE)), + c.getLong(c.getColumnIndex(MailboxColumns.ID)), + c.getString(c.getColumnIndex(MailboxColumns.DISPLAY_NAME)) + ); + } + + /** + * Return the message count which should be shown with a mailbox name. Depending on + * the mailbox type, we change what to show. + * + * @param mailboxType Such as {@link Mailbox#TYPE_INBOX} + * @param unreadCount Count obtained from {@link MailboxColumns#UNREAD_COUNT} + * @param totalCount Count obtained from {@link MailboxColumns#MESSAGE_COUNT} + */ + public int getMessageCount(int mailboxType, int unreadCount, int totalCount) { + switch (mailboxType) { + case Mailbox.TYPE_DRAFTS: + case Mailbox.TYPE_OUTBOX: + return totalCount; + case Mailbox.TYPE_SENT: + case Mailbox.TYPE_TRASH: + return 0; // We don't show a count for sent/trash. + } + return unreadCount; + } + + /** + * Same as {@link #getMessageCount(int, int, int)}, but gets information form a mailbox + * cursor. The cursor must contain the following columns: + * {@link MailboxColumns#TYPE}, {@link MailboxColumns#UNREAD_COUNT} and + * {@link MailboxColumns#MESSAGE_COUNT}. + */ + public int getMessageCount(Cursor mailboxCursor) { + final Cursor c = mailboxCursor; + return getMessageCount( + c.getInt(c.getColumnIndex(MailboxColumns.TYPE)), + c.getInt(c.getColumnIndex(MailboxColumns.UNREAD_COUNT)), + c.getInt(c.getColumnIndex(MailboxColumns.MESSAGE_COUNT)) + ); + } + /** * Lookup icons of special mailboxes */ diff --git a/src/com/android/email/activity/AccountSelectorAdapter.java b/src/com/android/email/activity/AccountSelectorAdapter.java index 364a3b8fe..60978ebbd 100644 --- a/src/com/android/email/activity/AccountSelectorAdapter.java +++ b/src/com/android/email/activity/AccountSelectorAdapter.java @@ -18,10 +18,12 @@ package com.android.email.activity; import com.google.common.annotations.VisibleForTesting; +import com.android.email.FolderProperties; import com.android.email.R; import com.android.email.data.ClosingMatrixCursor; import com.android.email.data.ThrottlingCursorLoader; import com.android.emailcommon.provider.Account; +import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.EmailContent.MailboxColumns; import com.android.emailcommon.provider.Mailbox; import com.android.emailcommon.utility.Utility; @@ -46,8 +48,8 @@ import android.widget.TextView; * TODO Test it! */ public class AccountSelectorAdapter extends CursorAdapter { - /** meta data column for an account's unread count */ - private static final String UNREAD_COUNT = "unreadCount"; + /** meta data column for an message count (unread or total, depending on row) */ + private static final String MESSAGE_COUNT = "unreadCount"; /** meta data column for the row type; used for display purposes */ private static final String ROW_TYPE = "rowType"; /** meta data position of the currently selected account in the drop-down list */ @@ -60,7 +62,7 @@ public class AccountSelectorAdapter extends CursorAdapter { static final int UNKNOWN_POSITION = -1; /** Projection for account database query */ private static final String[] ACCOUNT_PROJECTION = new String[] { - Account.ID, + EmailContent.RECORD_ID, Account.DISPLAY_NAME, Account.EMAIL_ADDRESS, }; @@ -70,10 +72,10 @@ public class AccountSelectorAdapter extends CursorAdapter { */ private static final String[] ADAPTER_PROJECTION = new String[] { ROW_TYPE, - Account.ID, + EmailContent.RECORD_ID, Account.DISPLAY_NAME, Account.EMAIL_ADDRESS, - UNREAD_COUNT, + MESSAGE_COUNT, ACCOUNT_POSITION, }; @@ -140,7 +142,7 @@ public class AccountSelectorAdapter extends CursorAdapter { if (c.getInt(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_HEADER) { view = mInflater.inflate(R.layout.account_selector_dropdown_header, parent, false); final TextView displayNameView = (TextView) view.findViewById(R.id.display_name); - final String displayName = getAccountDisplayName(c); + final String displayName = getDisplayName(c); displayNameView.setText(displayName); } else { view = mInflater.inflate(R.layout.account_selector_dropdown, parent, false); @@ -148,7 +150,7 @@ public class AccountSelectorAdapter extends CursorAdapter { final TextView emailAddressView = (TextView) view.findViewById(R.id.email_address); final TextView unreadCountView = (TextView) view.findViewById(R.id.unread_count); - final String displayName = getAccountDisplayName(position); + final String displayName = getDisplayName(position); final String emailAddress = getAccountEmailAddress(position); displayNameView.setText(displayName); @@ -162,11 +164,11 @@ public class AccountSelectorAdapter extends CursorAdapter { } boolean isAccount = isAccountItem(position); - long id = getAccountId(c); + long id = getId(c); if (isAccount || id != Mailbox.NO_MAILBOX) { unreadCountView.setVisibility(View.VISIBLE); unreadCountView.setText(UiUtilities.getMessageCountForUi(mContext, - getAccountUnreadCount(position), false)); + getAccountUnreadCount(position), true)); } else { unreadCountView.setVisibility(View.INVISIBLE); } @@ -177,7 +179,7 @@ public class AccountSelectorAdapter extends CursorAdapter { @Override public void bindView(View view, Context context, Cursor cursor) { TextView textView = (TextView) view.findViewById(R.id.display_name); - textView.setText(getAccountDisplayName(cursor)); + textView.setText(getDisplayName(cursor)); } @Override @@ -216,9 +218,9 @@ public class AccountSelectorAdapter extends CursorAdapter { return (c.getLong(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_MAILBOX); } - private String getAccountDisplayName(int position) { + private String getDisplayName(int position) { final Cursor c = getCursor(); - return c.moveToPosition(position) ? getAccountDisplayName(c) : null; + return c.moveToPosition(position) ? getDisplayName(c) : null; } private String getAccountEmailAddress(int position) { @@ -228,7 +230,7 @@ public class AccountSelectorAdapter extends CursorAdapter { private int getAccountUnreadCount(int position) { final Cursor c = getCursor(); - return c.moveToPosition(position) ? getAccountUnreadCount(c) : 0; + return c.moveToPosition(position) ? getMessageCount(c) : 0; } int getAccountPosition(int position) { @@ -236,13 +238,15 @@ public class AccountSelectorAdapter extends CursorAdapter { return c.moveToPosition(position) ? getAccountPosition(c) : UNKNOWN_POSITION; } - /** Returns the account ID extracted from the given cursor. */ - private static long getAccountId(Cursor c) { - return c.getLong(c.getColumnIndex(Account.ID)); + /** + * Returns the account/mailbox ID extracted from the given cursor. + */ + private static long getId(Cursor c) { + return c.getLong(c.getColumnIndex(EmailContent.RECORD_ID)); } /** Returns the account name extracted from the given cursor. */ - static String getAccountDisplayName(Cursor cursor) { + static String getDisplayName(Cursor cursor) { return cursor.getString(cursor.getColumnIndex(Account.DISPLAY_NAME)); } @@ -251,9 +255,12 @@ public class AccountSelectorAdapter extends CursorAdapter { return cursor.getString(cursor.getColumnIndex(Account.EMAIL_ADDRESS)); } - /** Returns the unread count extracted from the given cursor. */ - private static int getAccountUnreadCount(Cursor cursor) { - return cursor.getInt(cursor.getColumnIndex(UNREAD_COUNT)); + /** + * Returns the message count (unread or total, depending on row) extracted from the given + * cursor. + */ + private static int getMessageCount(Cursor cursor) { + return cursor.getInt(cursor.getColumnIndex(MESSAGE_COUNT)); } /** Returns the account position extracted from the given cursor. */ @@ -272,6 +279,7 @@ public class AccountSelectorAdapter extends CursorAdapter { private final Context mContext; private final long mAccountId; private final boolean mUseTwoPane; // Injectable for test + private final FolderProperties mFolderProperties; @VisibleForTesting AccountsLoader(Context context, long accountId, boolean useTwoPane) { @@ -280,6 +288,7 @@ public class AccountSelectorAdapter extends CursorAdapter { ORDER_BY); mContext = context; mAccountId = accountId; + mFolderProperties = FolderProperties.getInstance(mContext); mUseTwoPane = useTwoPane; } @@ -311,7 +320,7 @@ public class AccountSelectorAdapter extends CursorAdapter { final long accountId = accountCursor.getLong(0); final int unread = Mailbox.getUnreadCountByAccountAndMailboxType( mContext, accountId, Mailbox.TYPE_INBOX); - final String name = getAccountDisplayName(accountCursor); + final String name = getDisplayName(accountCursor); final String emailAddress = getAccountEmailAddress(accountCursor); addRow(matrixCursor, ROW_TYPE_ACCOUNT, accountId, name, emailAddress, unread, UNKNOWN_POSITION); @@ -361,25 +370,22 @@ public class AccountSelectorAdapter extends CursorAdapter { } int recentCount = (recentMailboxes == null) ? 0 : recentMailboxes.size(); matrixCursor.mRecentCount = recentCount; - if (recentCount > 0) { + + if (!mUseTwoPane) { + // "Recent mailboxes" header String mailboxHeader = mContext.getString( - R.string.mailbox_list_account_selector_mailbox_header_fmt, emailAddress); - addRow(matrixCursor, ROW_TYPE_HEADER, 0L, mailboxHeader, null, 0, UNKNOWN_POSITION); - for (long mailboxId : recentMailboxes) { - final int unread = Utility.getFirstRowInt(mContext, - ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId), - new String[] { MailboxColumns.UNREAD_COUNT }, null, null, null, 0); - final Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, mailboxId); - addRow(matrixCursor, ROW_TYPE_MAILBOX, mailboxId, mailbox.mDisplayName, null, - unread, accountPosition); - } - } else if (!mUseTwoPane) { - // Add the header for 'show all folders' - String mailboxHeader = mContext.getString( - R.string.mailbox_list_account_selector_mailbox_header_fmt, emailAddress); + R.string.mailbox_list_account_selector_mailbox_header_fmt, emailAddress); addRow(matrixCursor, ROW_TYPE_HEADER, 0L, mailboxHeader, null, 0, UNKNOWN_POSITION); } + + if (recentCount > 0) { + for (long mailboxId : recentMailboxes) { + addMailboxRow(matrixCursor, accountPosition, mailboxId); + } + } + if (!mUseTwoPane) { + // TODO We need this for combined view too. String name = mContext.getString( R.string.mailbox_list_account_selector_show_all_folders); addRow(matrixCursor, ROW_TYPE_MAILBOX, Mailbox.NO_MAILBOX, name, null, 0, @@ -387,15 +393,33 @@ public class AccountSelectorAdapter extends CursorAdapter { } } + + private static final String[] RECENT_MAILBOX_INFO_PROJECTION = new String[] { + MailboxColumns.ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, + MailboxColumns.UNREAD_COUNT, MailboxColumns.MESSAGE_COUNT + }; + + private void addMailboxRow(MatrixCursor matrixCursor, int accountPosition, long mailboxId) { + Cursor c = mContext.getContentResolver().query( + ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId), + RECENT_MAILBOX_INFO_PROJECTION, null, null, null); + if (!c.moveToFirst()) { + return; + } + addRow(matrixCursor, ROW_TYPE_MAILBOX, mailboxId, + mFolderProperties.getDisplayName(c), null, + mFolderProperties.getMessageCount(c), accountPosition); + } + /** Adds a row to the given cursor */ private void addRow(MatrixCursor cursor, int rowType, long id, String name, - String emailAddress, int unreadCount, int listPosition) { + String emailAddress, int messageCount, int listPosition) { cursor.newRow() .add(rowType) .add(id) .add(name) .add(emailAddress) - .add(unreadCount) + .add(messageCount) .add(listPosition); } } @@ -403,9 +427,9 @@ public class AccountSelectorAdapter extends CursorAdapter { /** Cursor with some extra meta data. */ static class CursorWithExtras extends ClosingMatrixCursor { /** Number of account elements, including the combined account row. */ - int mAccountCount; + private int mAccountCount; /** Number of recent mailbox elements */ - int mRecentCount; + private int mRecentCount; private CursorWithExtras(String[] columnNames, Cursor innerCursor) { super(columnNames, innerCursor); @@ -418,11 +442,19 @@ public class AccountSelectorAdapter extends CursorAdapter { int getPosition(long id) { moveToPosition(-1); while(moveToNext()) { - if (id == getAccountId(this)) { + if (id == getId(this)) { return getPosition(); } } return UNKNOWN_POSITION; } + + public int getAccountCount() { + return mAccountCount; + } + + public int getRecentMailboxCount() { + return mRecentCount; + } } } diff --git a/src/com/android/email/activity/ActionBarController.java b/src/com/android/email/activity/ActionBarController.java index 873747635..d94259258 100644 --- a/src/com/android/email/activity/ActionBarController.java +++ b/src/com/android/email/activity/ActionBarController.java @@ -19,6 +19,7 @@ package com.android.email.activity; import android.app.ActionBar; import android.app.LoaderManager; import android.app.LoaderManager.LoaderCallbacks; +import android.content.ContentUris; import android.content.Context; import android.content.Loader; import android.database.Cursor; @@ -30,9 +31,13 @@ import android.view.View; import android.widget.SearchView; import android.widget.TextView; +import com.android.email.FolderProperties; import com.android.email.R; +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.MailboxColumns; import com.android.emailcommon.provider.Mailbox; /** @@ -63,6 +68,8 @@ public class ActionBarController { private static final int LOADER_ID_ACCOUNT_LIST = EmailActivity.ACTION_BAR_CONTROLLER_LOADER_ID_BASE + 0; + private static final int LOADER_ID_MAILBOX + = EmailActivity.ACTION_BAR_CONTROLLER_LOADER_ID_BASE + 1; private final Context mContext; private final LoaderManager mLoaderManager; @@ -83,6 +90,9 @@ public class ActionBarController { /** The current account ID; used to determine if the account has changed. */ private long mLastAccountIdForDirtyCheck = Account.NO_ACCOUNT; + /** The current mailbox ID; used to determine if the mailbox has changed. */ + private long mLastMailboxIdForDirtyCheck = Mailbox.NO_MAILBOX; + /** Either {@link #MODE_NORMAL} or {@link #MODE_SEARCH}. */ private int mSearchMode = MODE_NORMAL; @@ -102,17 +112,15 @@ public class ActionBarController { */ public long getUIAccountId(); + /** + * @return currently selected mailbox ID, or {@link Mailbox#NO_MAILBOX} if no mailbox is + * selected. + */ + public long getMailboxId(); + /** @return true if the current mailbox name should be shown. */ public boolean shouldShowMailboxName(); - /** @return current mailbox name */ - public String getCurrentMailboxName(); - /** - * @return unread count for the current mailbox. (0 if the mailbox doesn't have the concept - * of "unread"; e.g. Drafts) - */ - public int getCurrentMailboxUnreadCount(); - /** @return the "UP" arrow should be shown. */ public boolean shouldShowUp(); @@ -278,14 +286,8 @@ public class ActionBarController { } else { mMailboxNameContainer.setVisibility(mCallback.shouldShowMailboxName() ? View.VISIBLE : View.GONE); - mMailboxNameView.setText(mCallback.getCurrentMailboxName()); } - // Note on action bar, we show only "unread count". Some mailboxes such as Outbox don't - // have the idea of "unread count", in which case we just omit the count. - mUnreadCountView.setText(UiUtilities.getMessageCountForUi(mContext, - mCallback.getCurrentMailboxUnreadCount(), true)); - // Update the account list only when the account has changed. if (mLastAccountIdForDirtyCheck != mCallback.getUIAccountId()) { mLastAccountIdForDirtyCheck = mCallback.getUIAccountId(); @@ -297,6 +299,17 @@ public class ActionBarController { updateAccountList(); } } + + // Update current mailbox info + final long mailboxId = mCallback.getMailboxId(); + if (mailboxId == Mailbox.NO_MAILBOX) { + clearMailboxInfo(); + } else { + if (mLastMailboxIdForDirtyCheck != mailboxId) { + mLastMailboxIdForDirtyCheck = mailboxId; + loadMailboxInfo(mailboxId); + } + } } /** @@ -345,7 +358,7 @@ public class ActionBarController { return; } - final int count = mAccountCursor.mAccountCount + mAccountCursor.mRecentCount; + final int count = mAccountCursor.getAccountCount() + mAccountCursor.getRecentMailboxCount(); if (count == 0) { mCallback.onNoAccountsFound(); return; @@ -359,7 +372,7 @@ public class ActionBarController { ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); if (selectedPosition >= 0) { mAccountCursor.moveToPosition(selectedPosition); - ab.setTitle(AccountSelectorAdapter.getAccountDisplayName(mAccountCursor)); + ab.setTitle(AccountSelectorAdapter.getDisplayName(mAccountCursor)); } return; } @@ -398,6 +411,47 @@ public class ActionBarController { } } + private static final String[] MAILBOX_NAME_COUNT_PROJECTION = new String[] { + MailboxColumns.ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, + MailboxColumns.UNREAD_COUNT, MailboxColumns.MESSAGE_COUNT + }; + + private void loadMailboxInfo(final long mailboxId) { + clearMailboxInfo(); + mLoaderManager.restartLoader(LOADER_ID_MAILBOX, null, + new LoaderCallbacks() { + @Override + public Loader onCreateLoader(int id, Bundle args) { + return new ThrottlingCursorLoader(mContext, + ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId), + MAILBOX_NAME_COUNT_PROJECTION, null, null, null); + } + + @Override + public void onLoadFinished(Loader loader, Cursor cursor) { + // Update action bar + FolderProperties fp = FolderProperties.getInstance(mContext); + updateMailboxInfo( + fp.getDisplayName(cursor), + fp.getMessageCount(cursor) + ); + } + + @Override + public void onLoaderReset(Loader loader) { + } + }); + } + + private void clearMailboxInfo() { + updateMailboxInfo("", 0); + } + + private void updateMailboxInfo(String mailboxName, int count) { + mMailboxNameView.setText(mailboxName); + mUnreadCountView.setText(UiUtilities.getMessageCountForUi(mContext, count, true)); + } + private final SearchView.OnQueryTextListener mOnQueryText = new SearchView.OnQueryTextListener() { @Override diff --git a/src/com/android/email/activity/MailboxFragmentAdapter.java b/src/com/android/email/activity/MailboxFragmentAdapter.java index e5b7e6ba7..d77f16bbe 100644 --- a/src/com/android/email/activity/MailboxFragmentAdapter.java +++ b/src/com/android/email/activity/MailboxFragmentAdapter.java @@ -16,8 +16,6 @@ package com.android.email.activity; -import com.google.common.annotations.VisibleForTesting; - import com.android.email.Email; import com.android.email.FolderProperties; import com.android.email.R; @@ -32,8 +30,7 @@ import com.android.emailcommon.provider.EmailContent.MailboxColumns; import com.android.emailcommon.provider.EmailContent.Message; import com.android.emailcommon.provider.Mailbox; import com.android.emailcommon.utility.Utility; - -import java.util.ArrayList; +import com.google.common.annotations.VisibleForTesting; import android.content.ContentUris; import android.content.Context; @@ -52,6 +49,8 @@ import android.widget.CursorAdapter; import android.widget.ImageView; import android.widget.TextView; +import java.util.ArrayList; + /** * Mailbox cursor adapter for the mailbox list fragment. * @@ -233,45 +232,6 @@ class MailboxFragmentAdapter extends CursorAdapter { return getRowType(cursor) == ROW_TYPE_ACCOUNT; } - /** - * Returns the type of count to use for the given row. - */ - private int getCountType(Cursor cursor) { - if (isAccountRow(cursor)) { - return COUNT_TYPE_UNREAD; - } - // otherwise, look at mailbox type to determine the count - switch (cursor.getInt(cursor.getColumnIndex(MailboxColumns.TYPE))) { - case Mailbox.TYPE_DRAFTS: - case Mailbox.TYPE_OUTBOX: - return COUNT_TYPE_TOTAL; - case Mailbox.TYPE_SENT: - case Mailbox.TYPE_TRASH: - return COUNT_TYPE_NO_COUNT; - } - return COUNT_TYPE_UNREAD; - } - - /** - * Returns the unread count for the given row if the count type is {@link #COUNT_TYPE_UNREAD}. - * Otherwise, {@code 0}. - */ - int getUnreadCount(int position) { - Cursor c = (Cursor) getItem(position); - if (getCountType(c) != COUNT_TYPE_UNREAD) { - return 0; // Don't have a unread count. - } - return c.getInt(c.getColumnIndex(MailboxColumns.UNREAD_COUNT)); - } - - /** - * Returns the display name for the given row. - */ - String getDisplayName(Context context, int position) { - Cursor c = (Cursor) getItem(position); - return getDisplayName(context, c); - } - /** * Returns the ID of the given row. It may be a mailbox or account ID depending upon the * result of {@link #isAccountRow}. @@ -301,18 +261,17 @@ class MailboxFragmentAdapter extends CursorAdapter { } private static String getDisplayName(Context context, Cursor cursor) { - String name = null; - if (getRowType(cursor) == ROW_TYPE_MAILBOX) { - // If it's a mailbox (as opposed to account row in combined view), and of certain types, - // we use the predefined names. - final int type = getType(cursor); - final long mailboxId = getId(cursor); - name = FolderProperties.getInstance(context).getDisplayName(type, mailboxId); + final String name = cursor.getString(cursor.getColumnIndex(MailboxColumns.DISPLAY_NAME)); + if (isAccountRow(cursor)) { + // Always use actual name + return name; + } else { + // Use this method for two purposes: + // - Set combined mailbox names + // - Rewrite special mailbox names (e.g. trash) + FolderProperties fp = FolderProperties.getInstance(context); + return fp.getDisplayName(getType(cursor), getId(cursor), name); } - if (name == null) { - name = cursor.getString(cursor.getColumnIndex(MailboxColumns.DISPLAY_NAME)); - } - return name; } static long getId(Cursor cursor) { @@ -394,16 +353,11 @@ class MailboxFragmentAdapter extends CursorAdapter { nameView.setText(getDisplayName(context, cursor)); // Set count final int count; - switch (getCountType(cursor)) { - case COUNT_TYPE_UNREAD: - count = getUnreadCount(cursor); - break; - case COUNT_TYPE_TOTAL: - count = getMessageCount(cursor); - break; - default: // no count - count = 0; - break; + if (isAccountRow(cursor)) { + count = getUnreadCount(cursor); + } else { + FolderProperties fp = FolderProperties.getInstance(context); + count = fp.getMessageCount(type, getUnreadCount(cursor), getMessageCount(cursor)); } final TextView countView = (TextView) view.findViewById(R.id.message_count); diff --git a/src/com/android/email/activity/MailboxListFragment.java b/src/com/android/email/activity/MailboxListFragment.java index e5bac3a97..ff50afb0e 100644 --- a/src/com/android/email/activity/MailboxListFragment.java +++ b/src/com/android/email/activity/MailboxListFragment.java @@ -239,24 +239,6 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList /** Called when an account is selected on the combined view. */ public void onAccountSelected(long accountId); - /** - * TODO Remove it. The behavior is not well-defined. (Won't get called when highlight is - * disabled.) - * It was added only to update the action bar with the current mailbox name and the - * message count. Remove it and make the action bar watch the mailbox by itself. - * - * Called when the list updates to propagate the current mailbox name and the unread count - * for it. - * - * Note the reason why it's separated from onMailboxSelected is because this needs to be - * reported when the unread count changes without changing the current mailbox. - * - * @param mailboxId ID for the selected mailbox. It'll never be of a combined mailbox, - * and the owner account ID is always the same as - * {@link MailboxListFragment#getAccountId()}. - */ - public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount); - /** * Called when the parent mailbox is changing. */ @@ -268,8 +250,6 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList @Override public void onMailboxSelected(long accountId, long mailboxId, boolean nestedNavigation) { } @Override public void onAccountSelected(long accountId) { } - @Override public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, - int unreadCount) { } @Override public void onParentMailboxChanged() { } } @@ -882,8 +862,6 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList } final ListView lv = getListView(); boolean found = false; - String mailboxName = ""; - int unreadCount = 0; if (mHighlightedMailboxId == Mailbox.NO_MAILBOX) { // No mailbox selected lv.clearChoices(); @@ -900,14 +878,10 @@ public class MailboxListFragment extends ListFragment implements OnItemClickList if (ensureSelectionVisible) { Utility.listViewSmoothScrollToPosition(getActivity(), lv, i); } - mailboxName = mListAdapter.getDisplayName(mActivity, i); - unreadCount = mListAdapter.getUnreadCount(i); break; } } - if (found) { - mCallback.onCurrentMailboxUpdated(mHighlightedMailboxId, mailboxName, unreadCount); - } else { + if (!found) { mHighlightedMailboxId = Mailbox.NO_MAILBOX; } return found; diff --git a/src/com/android/email/activity/MailboxMoveToAdapter.java b/src/com/android/email/activity/MailboxMoveToAdapter.java index 2a447932a..5159a3dfd 100644 --- a/src/com/android/email/activity/MailboxMoveToAdapter.java +++ b/src/com/android/email/activity/MailboxMoveToAdapter.java @@ -130,11 +130,8 @@ class MailboxMoveToAdapter extends CursorAdapter { private static String getDisplayText(Context context, Cursor cursor) { final int type = cursor.getInt(COLUMN_TYPE); final long mailboxId = cursor.getLong(COLUMN_ID); - String name = FolderProperties.getInstance(context).getDisplayName(type, mailboxId); - if (name == null) { - name = cursor.getString(COLUMN_MAILBOX_NAME); - } - return name; + return FolderProperties.getInstance(context).getDisplayName(type, mailboxId, + cursor.getString(COLUMN_MAILBOX_NAME)); } /** Loader for the "move to mailbox" dialog. */ diff --git a/src/com/android/email/activity/UIControllerOnePane.java b/src/com/android/email/activity/UIControllerOnePane.java index f6511b746..dd564a340 100644 --- a/src/com/android/email/activity/UIControllerOnePane.java +++ b/src/com/android/email/activity/UIControllerOnePane.java @@ -58,11 +58,6 @@ class UIControllerOnePane extends UIControllerBase { switchAccount(accountId); } - // MailboxListFragment.Callback - @Override - public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount) { - } - // MailboxListFragment.Callback @Override public void onMailboxSelected(long accountId, long mailboxId, boolean nestedNavigation) { @@ -211,15 +206,6 @@ class UIControllerOnePane extends UIControllerBase { return false; // no mailbox name/unread count. } - @Override - public String getCurrentMailboxName() { - return null; // no mailbox name/unread count. - } - - @Override - public int getCurrentMailboxUnreadCount() { - return 0; // no mailbox name/unread count. - } @Override public boolean shouldShowUp() { @@ -232,6 +218,11 @@ class UIControllerOnePane extends UIControllerBase { return UIControllerOnePane.this.getUIAccountId(); } + @Override + public long getMailboxId() { + return UIControllerOnePane.this.getMailboxId(); + } + @Override public void onMailboxSelected(long mailboxId) { if (mailboxId == Mailbox.NO_MAILBOX) { diff --git a/src/com/android/email/activity/UIControllerTwoPane.java b/src/com/android/email/activity/UIControllerTwoPane.java index abf82ed17..fa41dce20 100644 --- a/src/com/android/email/activity/UIControllerTwoPane.java +++ b/src/com/android/email/activity/UIControllerTwoPane.java @@ -63,20 +63,6 @@ class UIControllerTwoPane extends UIControllerBase implements private final MessageOrderManagerCallback mMessageOrderManagerCallback = new MessageOrderManagerCallback(); - /** - * The mailbox name selected on the mailbox list. - * Passed via {@link #onCurrentMailboxUpdated}. - */ - private String mCurrentMailboxName; - - /** - * The unread count for the mailbox selected on the mailbox list. - * Passed via {@link #onCurrentMailboxUpdated}. - * - * 0 if the mailbox doesn't have the concept of "unread". e.g. Drafts. - */ - private int mCurrentMailboxUnreadCount; - public UIControllerTwoPane(EmailActivity activity) { super(activity); } @@ -120,14 +106,6 @@ class UIControllerTwoPane extends UIControllerBase implements switchAccount(accountId); } - // MailboxListFragment$Callback - @Override - public void onCurrentMailboxUpdated(long mailboxId, String mailboxName, int unreadCount) { - mCurrentMailboxName = mailboxName; - mCurrentMailboxUnreadCount = unreadCount; - refreshActionBar(); - } - // MailboxListFragment$Callback @Override public void onParentMailboxChanged() { @@ -822,21 +800,17 @@ class UIControllerTwoPane extends UIControllerBase implements } private class ActionBarControllerCallback implements ActionBarController.Callback { - @Override - public String getCurrentMailboxName() { - return mCurrentMailboxName; - } - - @Override - public int getCurrentMailboxUnreadCount() { - return mCurrentMailboxUnreadCount; - } @Override public long getUIAccountId() { return UIControllerTwoPane.this.getUIAccountId(); } + @Override + public long getMailboxId() { + return UIControllerTwoPane.this.getMessageListMailboxId(); + } + @Override public boolean isAccountSelected() { return UIControllerTwoPane.this.isAccountSelected(); diff --git a/tests/src/com/android/email/FolderPropertiesTests.java b/tests/src/com/android/email/FolderPropertiesTests.java new file mode 100644 index 000000000..de95a6e05 --- /dev/null +++ b/tests/src/com/android/email/FolderPropertiesTests.java @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2011 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; + +import com.android.emailcommon.provider.EmailContent.MailboxColumns; +import com.android.emailcommon.provider.Mailbox; + +import android.content.Context; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.graphics.drawable.Drawable; +import android.test.AndroidTestCase; + +import java.util.HashSet; +import java.util.Set; + +public class FolderPropertiesTests extends AndroidTestCase { + + private static Cursor buildCursor(String[] columns, Object... values) { + MatrixCursor c = new MatrixCursor(columns, 1); + c.addRow(values); + c.moveToFirst(); + return c; + } + + /** + * Tests of the syncronization of array and types of the display folder names + */ + public void testGetDisplayName() { + Context context = getContext(); + FolderProperties fp = FolderProperties.getInstance(context); + + assertEquals( + context.getString(R.string.mailbox_name_display_inbox), + fp.getDisplayName(Mailbox.TYPE_INBOX, 0, "ignored")); + + assertEquals( + "*name*", + fp.getDisplayName(Mailbox.TYPE_MAIL, 0, "*name*")); + + assertEquals( + "*name2*", + fp.getDisplayName(Mailbox.TYPE_PARENT, 0, "*name2*")); + + assertEquals( + context.getString(R.string.mailbox_name_display_drafts), + fp.getDisplayName(Mailbox.TYPE_DRAFTS, 0, "ignored")); + + assertEquals( + context.getString(R.string.mailbox_name_display_outbox), + fp.getDisplayName(Mailbox.TYPE_OUTBOX, 0, "ignored")); + + assertEquals( + context.getString(R.string.mailbox_name_display_sent), + fp.getDisplayName(Mailbox.TYPE_SENT, 0, "ignored")); + + assertEquals( + context.getString(R.string.mailbox_name_display_trash), + fp.getDisplayName(Mailbox.TYPE_TRASH, 0, "ignored")); + + assertEquals( + context.getString(R.string.mailbox_name_display_junk), + fp.getDisplayName(Mailbox.TYPE_JUNK, 0, "ignored")); + + // Testing illegal index + assertEquals( + "some name", + fp.getDisplayName(8, 12345678890L, "some name")); + + + // Combined mailboxes + assertEquals( + context.getString(R.string.account_folder_list_summary_inbox), + fp.getDisplayName(0, Mailbox.QUERY_ALL_INBOXES, "ignored")); + assertEquals( + context.getString(R.string.account_folder_list_summary_starred), + fp.getDisplayName(0, Mailbox.QUERY_ALL_FAVORITES, "ignored")); + assertEquals( + context.getString(R.string.account_folder_list_summary_drafts), + fp.getDisplayName(0, Mailbox.QUERY_ALL_DRAFTS, "ignored")); + assertEquals( + context.getString(R.string.account_folder_list_summary_outbox), + fp.getDisplayName(0, Mailbox.QUERY_ALL_OUTBOX, "ignored")); + } + + public void testGetDisplayNameWithCursor() { + Context context = getContext(); + FolderProperties fp = FolderProperties.getInstance(context); + String[] columns = new String[] {MailboxColumns.ID, MailboxColumns.TYPE, + MailboxColumns.DISPLAY_NAME}; + + assertEquals( + context.getString(R.string.mailbox_name_display_inbox), + fp.getDisplayName(buildCursor(columns, 1, Mailbox.TYPE_INBOX, "ignored")) + ); + + assertEquals( + "name", + fp.getDisplayName(buildCursor(columns, 1, Mailbox.TYPE_MAIL, "name")) + ); + } + + /** + * Confirm that all of the special icons are available and unique + */ + public void testSpecialIcons() { + FolderProperties fp = FolderProperties.getInstance(mContext); + + // Make sure they're available + Drawable inbox = fp.getIcon(Mailbox.TYPE_INBOX, -1, 0); + Drawable mail = fp.getIcon(Mailbox.TYPE_MAIL, -1, 0); + Drawable parent = fp.getIcon(Mailbox.TYPE_PARENT, -1, 0); + Drawable drafts = fp.getIcon(Mailbox.TYPE_DRAFTS, -1, 0); + Drawable outbox = fp.getIcon(Mailbox.TYPE_OUTBOX, -1, 0); + Drawable sent = fp.getIcon(Mailbox.TYPE_SENT, -1, 0); + Drawable trash = fp.getIcon(Mailbox.TYPE_TRASH, -1, 0); + Drawable junk = fp.getIcon(Mailbox.TYPE_JUNK, -1, 0); + + // Make sure they're unique + Set set = new HashSet(); + set.add(inbox); + set.add(parent); + set.add(drafts); + set.add(outbox); + set.add(sent); + set.add(trash); + set.add(junk); + assertEquals(7, set.size()); + + assertNull(mail); + } + + public void testGetMessageCountWithCursor() { + Context context = getContext(); + FolderProperties fp = FolderProperties.getInstance(context); + String[] columns = new String[] {MailboxColumns.TYPE, MailboxColumns.UNREAD_COUNT, + MailboxColumns.MESSAGE_COUNT}; + + assertEquals( + 1, + fp.getMessageCount(buildCursor(columns, Mailbox.TYPE_INBOX, 1, 2)) + ); + assertEquals( + 1, + fp.getMessageCount(buildCursor(columns, Mailbox.TYPE_MAIL, 1, 2)) + ); + + assertEquals( + 2, + fp.getMessageCount(buildCursor(columns, Mailbox.TYPE_DRAFTS, 1, 2)) + ); + assertEquals( + 2, + fp.getMessageCount(buildCursor(columns, Mailbox.TYPE_OUTBOX, 1, 2)) + ); + + assertEquals( + 0, + fp.getMessageCount(buildCursor(columns, Mailbox.TYPE_TRASH, 1, 2)) + ); + + assertEquals( + 0, + fp.getMessageCount(buildCursor(columns, Mailbox.TYPE_SENT, 1, 2)) + ); + } +} diff --git a/tests/src/com/android/email/activity/AccountSelectorAdapterAccountsLoaderTest.java b/tests/src/com/android/email/activity/AccountSelectorAdapterAccountsLoaderTest.java index 36e801407..97b0a6712 100644 --- a/tests/src/com/android/email/activity/AccountSelectorAdapterAccountsLoaderTest.java +++ b/tests/src/com/android/email/activity/AccountSelectorAdapterAccountsLoaderTest.java @@ -55,9 +55,9 @@ public class AccountSelectorAdapterAccountsLoaderTest extends LoaderTestCase { true); AccountSelectorAdapter.CursorWithExtras result = (AccountSelectorAdapter.CursorWithExtras) getLoaderResultSynchronously(l); - assertEquals(1, result.mAccountCount); + assertEquals(1, result.getAccountCount()); assertEquals(2, result.getCount()); // +1 as the cursor has the header row - assertEquals(0, result.mRecentCount); // No recent in two-pane account spinner. + assertEquals(0, result.getRecentMailboxCount()); // No recent on two-pane. } final Account a2 = ProviderTestUtils.setupAccount("a2", true, mProviderContext); @@ -67,9 +67,9 @@ public class AccountSelectorAdapterAccountsLoaderTest extends LoaderTestCase { true); AccountSelectorAdapter.CursorWithExtras result = (AccountSelectorAdapter.CursorWithExtras) getLoaderResultSynchronously(l); - assertEquals(3, result.mAccountCount); + assertEquals(3, result.getAccountCount()); assertEquals(4, result.getCount()); // +1 as the cursor has the header row - assertEquals(0, result.mRecentCount); // No recent in two-pane account spinner. + assertEquals(0, result.getRecentMailboxCount()); // No recent on two-pane. } } } diff --git a/tests/src/com/android/emailcommon/utility/UtilityUnitTests.java b/tests/src/com/android/emailcommon/utility/UtilityUnitTests.java index bdd4b5848..fa3110086 100644 --- a/tests/src/com/android/emailcommon/utility/UtilityUnitTests.java +++ b/tests/src/com/android/emailcommon/utility/UtilityUnitTests.java @@ -17,7 +17,6 @@ package com.android.emailcommon.utility; import com.android.email.DBTestHelper; -import com.android.email.FolderProperties; import com.android.email.R; import com.android.email.TestUtils; import com.android.email.provider.ProviderTestUtils; @@ -61,71 +60,6 @@ import java.util.Set; */ @SmallTest public class UtilityUnitTests extends AndroidTestCase { - /** - * Tests of the syncronization of array and types of the display folder names - */ - public void testGetDisplayName() { - Context context = getContext(); - String expect, name; - expect = context.getString(R.string.mailbox_name_display_inbox); - name = FolderProperties.getInstance(context).getDisplayName(Mailbox.TYPE_INBOX); - assertEquals(expect, name); - expect = null; - name = FolderProperties.getInstance(context).getDisplayName(Mailbox.TYPE_MAIL); - assertEquals(expect, name); - expect = null; - name = FolderProperties.getInstance(context).getDisplayName(Mailbox.TYPE_PARENT); - assertEquals(expect, name); - expect = context.getString(R.string.mailbox_name_display_drafts); - name = FolderProperties.getInstance(context).getDisplayName(Mailbox.TYPE_DRAFTS); - assertEquals(expect, name); - expect = context.getString(R.string.mailbox_name_display_outbox); - name = FolderProperties.getInstance(context).getDisplayName(Mailbox.TYPE_OUTBOX); - assertEquals(expect, name); - expect = context.getString(R.string.mailbox_name_display_sent); - name = FolderProperties.getInstance(context).getDisplayName(Mailbox.TYPE_SENT); - assertEquals(expect, name); - expect = context.getString(R.string.mailbox_name_display_trash); - name = FolderProperties.getInstance(context).getDisplayName(Mailbox.TYPE_TRASH); - assertEquals(expect, name); - expect = context.getString(R.string.mailbox_name_display_junk); - name = FolderProperties.getInstance(context).getDisplayName(Mailbox.TYPE_JUNK); - assertEquals(expect, name); - // Testing illegal index - expect = null; - name = FolderProperties.getInstance(context).getDisplayName(8); - assertEquals(expect, name); - } - - /** - * Confirm that all of the special icons are available and unique - */ - public void testSpecialIcons() { - FolderProperties fp = FolderProperties.getInstance(mContext); - - // Make sure they're available - Drawable inbox = fp.getIcon(Mailbox.TYPE_INBOX, -1, 0); - Drawable mail = fp.getIcon(Mailbox.TYPE_MAIL, -1, 0); - Drawable parent = fp.getIcon(Mailbox.TYPE_PARENT, -1, 0); - Drawable drafts = fp.getIcon(Mailbox.TYPE_DRAFTS, -1, 0); - Drawable outbox = fp.getIcon(Mailbox.TYPE_OUTBOX, -1, 0); - Drawable sent = fp.getIcon(Mailbox.TYPE_SENT, -1, 0); - Drawable trash = fp.getIcon(Mailbox.TYPE_TRASH, -1, 0); - Drawable junk = fp.getIcon(Mailbox.TYPE_JUNK, -1, 0); - - // Make sure they're unique - Set set = new HashSet(); - set.add(inbox); - set.add(parent); - set.add(drafts); - set.add(outbox); - set.add(sent); - set.add(trash); - set.add(junk); - assertEquals(7, set.size()); - - assertNull(mail); - } private static byte[] b(int... array) { return TestUtils.b(array);