1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.email.activity; 18 19 import android.content.ContentResolver; 20 import android.content.ContentUris; 21 import android.content.Context; 22 import android.content.Loader; 23 import android.database.Cursor; 24 import android.database.MatrixCursor; 25 import android.view.LayoutInflater; 26 import android.view.View; 27 import android.view.ViewGroup; 28 import android.widget.AdapterView; 29 import android.widget.CursorAdapter; 30 import android.widget.TextView; 31 32 import com.android.email.FolderProperties; 33 import com.android.email.R; 34 import com.android.email.ResourceHelper; 35 import com.android.email.data.ClosingMatrixCursor; 36 import com.android.email.data.ThrottlingCursorLoader; 37 import com.android.emailcommon.provider.Account; 38 import com.android.emailcommon.provider.EmailContent; 39 import com.android.emailcommon.provider.EmailContent.AccountColumns; 40 import com.android.emailcommon.provider.EmailContent.MailboxColumns; 41 import com.android.emailcommon.provider.Mailbox; 42 import com.android.emailcommon.utility.Utility; 43 import com.google.common.annotations.VisibleForTesting; 44 import com.google.common.base.Preconditions; 45 46 import java.util.ArrayList; 47 import java.util.Collection; 48 49 /** 50 * Account selector spinner. 51 * 52 * TODO Test it! 53 */ 54 public class AccountSelectorAdapter extends CursorAdapter { 55 /** meta data column for an message count (unread or total, depending on row) */ 56 private static final String MESSAGE_COUNT = "unreadCount"; 57 58 /** meta data column for the row type; used for display purposes */ 59 private static final String ROW_TYPE = "rowType"; 60 61 /** meta data position of the currently selected account in the drop-down list */ 62 private static final String ACCOUNT_POSITION = "accountPosition"; 63 64 /** "account id" virtual column name for the matrix cursor */ 65 private static final String ACCOUNT_ID = "accountId"; 66 67 private static final int ROW_TYPE_HEADER = AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER; 68 @SuppressWarnings("unused") 69 private static final int ROW_TYPE_MAILBOX = 0; 70 private static final int ROW_TYPE_ACCOUNT = 1; 71 private static final int ITEM_VIEW_TYPE_ACCOUNT = 0; 72 static final int UNKNOWN_POSITION = -1; 73 /** Projection for account database query */ 74 private static final String[] ACCOUNT_PROJECTION = new String[] { 75 EmailContent.RECORD_ID, 76 Account.DISPLAY_NAME, 77 Account.EMAIL_ADDRESS, 78 }; 79 /** 80 * Projection used for the selector display; we add meta data that doesn't exist in the 81 * account database, so, this should be a super-set of {@link #ACCOUNT_PROJECTION}. 82 */ 83 private static final String[] ADAPTER_PROJECTION = new String[] { 84 ROW_TYPE, 85 EmailContent.RECORD_ID, 86 Account.DISPLAY_NAME, 87 Account.EMAIL_ADDRESS, 88 MESSAGE_COUNT, 89 ACCOUNT_POSITION, // TODO Probably we don't really need this 90 ACCOUNT_ID, 91 }; 92 93 /** Sort order. Show the default account first. */ 94 private static final String ORDER_BY = Account.IS_DEFAULT + " desc, " + Account.RECORD_ID; 95 96 @SuppressWarnings("hiding") 97 private final Context mContext; 98 private final LayoutInflater mInflater; 99 private final ResourceHelper mResourceHelper; 100 101 /** 102 * Returns a loader that can populate the account spinner. 103 * @param context a context 104 * @param accountId the ID of the currently viewed account 105 */ createLoader(Context context, long accountId, long mailboxId)106 public static Loader<Cursor> createLoader(Context context, long accountId, long mailboxId) { 107 return new AccountsLoader(context, accountId, mailboxId, UiUtilities.useTwoPane(context)); 108 } 109 AccountSelectorAdapter(Context context)110 public AccountSelectorAdapter(Context context) { 111 super(context, null, 0 /* no auto-requery */); 112 mContext = context; 113 mInflater = LayoutInflater.from(context); 114 mResourceHelper = ResourceHelper.getInstance(context); 115 } 116 117 /** 118 * {@inheritDoc} 119 * 120 * The account selector view can contain one of four types of row data: 121 * <ol> 122 * <li>headers</li> 123 * <li>accounts</li> 124 * <li>recent mailboxes</li> 125 * <li>"show all folders"</li> 126 * </ol> 127 * Headers are handled separately as they have a unique layout and cannot be interacted with. 128 * Accounts, recent mailboxes and "show all folders" all have the same interaction model and 129 * share a very similar layout. The single difference is that both accounts and recent 130 * mailboxes display an unread count; whereas "show all folders" does not. To determine 131 * if a particular row is "show all folders" verify that a) it's not an account row and 132 * b) it's ID is {@link Mailbox#NO_MAILBOX}. 133 * 134 * TODO Use recycled views. ({@link #getViewTypeCount} and {@link #getItemViewType}) 135 */ 136 @Override getView(int position, View convertView, ViewGroup parent)137 public View getView(int position, View convertView, ViewGroup parent) { 138 Cursor c = getCursor(); 139 c.moveToPosition(position); 140 View view; 141 if (c.getInt(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_HEADER) { 142 view = mInflater.inflate(R.layout.action_bar_spinner_dropdown_header, parent, false); 143 final TextView displayNameView = (TextView) view.findViewById(R.id.display_name); 144 final String displayName = getDisplayName(c); 145 displayNameView.setText(displayName); 146 } else { 147 view = mInflater.inflate(R.layout.action_bar_spinner_dropdown, parent, false); 148 final TextView displayNameView = (TextView) view.findViewById(R.id.display_name); 149 final TextView emailAddressView = (TextView) view.findViewById(R.id.email_address); 150 final TextView unreadCountView = (TextView) view.findViewById(R.id.unread_count); 151 final View chipView = view.findViewById(R.id.color_chip); 152 153 final String displayName = getDisplayName(c); 154 final String emailAddress = getAccountEmailAddress(c); 155 156 displayNameView.setText(displayName); 157 158 // Show the email address only when it's different from the display name. 159 boolean isAccount = isAccountItem(c); 160 if (displayName.equals(emailAddress) || !isAccount) { 161 emailAddressView.setVisibility(View.GONE); 162 } else { 163 emailAddressView.setVisibility(View.VISIBLE); 164 emailAddressView.setText(emailAddress); 165 } 166 167 long id = getId(c); 168 if (isAccount || id != Mailbox.NO_MAILBOX) { 169 unreadCountView.setVisibility(View.VISIBLE); 170 unreadCountView.setText(UiUtilities.getMessageCountForUi(mContext, 171 getAccountUnreadCount(c), true)); 172 173 // If we're on a combined account, show the color chip indicators for all real 174 // accounts so it can be used as a legend. 175 boolean isCombinedActive = 176 ((CursorWithExtras) c).getAccountId() == Account.ACCOUNT_ID_COMBINED_VIEW; 177 178 if (isCombinedActive && Account.isNormalAccount(id)) { 179 chipView.setBackgroundColor(mResourceHelper.getAccountColor(id)); 180 chipView.setVisibility(View.VISIBLE); 181 } else { 182 chipView.setVisibility(View.GONE); 183 } 184 } else { 185 unreadCountView.setVisibility(View.INVISIBLE); 186 chipView.setVisibility(View.GONE); 187 } 188 189 } 190 return view; 191 } 192 193 @Override newView(Context context, Cursor cursor, ViewGroup parent)194 public View newView(Context context, Cursor cursor, ViewGroup parent) { 195 return null; // we don't reuse views. This method never gets called. 196 } 197 198 @Override bindView(View view, Context context, Cursor cursor)199 public void bindView(View view, Context context, Cursor cursor) { 200 // we don't reuse views. This method never gets called. 201 } 202 203 @Override getViewTypeCount()204 public int getViewTypeCount() { 205 return 2; 206 } 207 208 @Override getItemViewType(int position)209 public int getItemViewType(int position) { 210 Cursor c = getCursor(); 211 c.moveToPosition(position); 212 return c.getLong(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_HEADER 213 ? AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER 214 : ITEM_VIEW_TYPE_ACCOUNT; 215 } 216 217 @Override isEnabled(int position)218 public boolean isEnabled(int position) { 219 return (getItemViewType(position) != AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER); 220 } 221 isAccountItem(int position)222 public boolean isAccountItem(int position) { 223 Cursor c = getCursor(); 224 c.moveToPosition(position); 225 return isAccountItem(c); 226 } 227 isAccountItem(Cursor c)228 public boolean isAccountItem(Cursor c) { 229 return (c.getLong(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_ACCOUNT); 230 } 231 isMailboxItem(int position)232 public boolean isMailboxItem(int position) { 233 Cursor c = getCursor(); 234 c.moveToPosition(position); 235 return (c.getLong(c.getColumnIndex(ROW_TYPE)) == ROW_TYPE_MAILBOX); 236 } 237 getAccountUnreadCount(Cursor c)238 private int getAccountUnreadCount(Cursor c) { 239 return getMessageCount(c); 240 } 241 242 /** 243 * Returns the account/mailbox ID extracted from the given cursor. 244 */ getId(Cursor c)245 private static long getId(Cursor c) { 246 return c.getLong(c.getColumnIndex(EmailContent.RECORD_ID)); 247 } 248 249 /** 250 * @return ID of the account / mailbox for a row 251 */ getId(int position)252 public long getId(int position) { 253 final Cursor c = getCursor(); 254 return c.moveToPosition(position) ? getId(c) : Account.NO_ACCOUNT; 255 } 256 257 /** 258 * @return ID of the account for a row 259 */ getAccountId(int position)260 public long getAccountId(int position) { 261 final Cursor c = getCursor(); 262 return c.moveToPosition(position) 263 ? c.getLong(c.getColumnIndex(ACCOUNT_ID)) 264 : Account.NO_ACCOUNT; 265 } 266 267 /** Returns the account name extracted from the given cursor. */ getDisplayName(Cursor cursor)268 static String getDisplayName(Cursor cursor) { 269 return cursor.getString(cursor.getColumnIndex(Account.DISPLAY_NAME)); 270 } 271 272 /** Returns the email address extracted from the given cursor. */ getAccountEmailAddress(Cursor cursor)273 private static String getAccountEmailAddress(Cursor cursor) { 274 return cursor.getString(cursor.getColumnIndex(Account.EMAIL_ADDRESS)); 275 } 276 277 /** 278 * Returns the message count (unread or total, depending on row) extracted from the given 279 * cursor. 280 */ getMessageCount(Cursor cursor)281 private static int getMessageCount(Cursor cursor) { 282 return cursor.getInt(cursor.getColumnIndex(MESSAGE_COUNT)); 283 } 284 285 private static String sCombinedViewDisplayName; getCombinedViewDisplayName(Context c)286 private static String getCombinedViewDisplayName(Context c) { 287 if (sCombinedViewDisplayName == null) { 288 sCombinedViewDisplayName = c.getResources().getString( 289 R.string.mailbox_list_account_selector_combined_view); 290 } 291 return sCombinedViewDisplayName; 292 } 293 294 /** 295 * Load the account list. The resulting cursor contains 296 * - Account info 297 * - # of unread messages in inbox 298 * - The "Combined view" row if there's more than one account. 299 */ 300 @VisibleForTesting 301 static class AccountsLoader extends ThrottlingCursorLoader { 302 private final Context mContext; 303 private final long mAccountId; 304 private final long mMailboxId; 305 private final boolean mUseTwoPane; // Injectable for test 306 private final FolderProperties mFolderProperties; 307 308 @VisibleForTesting AccountsLoader(Context context, long accountId, long mailboxId, boolean useTwoPane)309 AccountsLoader(Context context, long accountId, long mailboxId, boolean useTwoPane) { 310 // Super class loads a regular account cursor, but we replace it in loadInBackground(). 311 super(context, Account.CONTENT_URI, ACCOUNT_PROJECTION, null, null, 312 ORDER_BY); 313 mContext = context; 314 mAccountId = accountId; 315 mMailboxId = mailboxId; 316 mFolderProperties = FolderProperties.getInstance(mContext); 317 mUseTwoPane = useTwoPane; 318 } 319 320 @Override loadInBackground()321 public Cursor loadInBackground() { 322 final Cursor accountsCursor = super.loadInBackground(); 323 // Use ClosingMatrixCursor so that accountsCursor gets closed too when it's closed. 324 final CursorWithExtras resultCursor 325 = new CursorWithExtras(ADAPTER_PROJECTION, accountsCursor); 326 final int accountPosition = addAccountsToCursor(resultCursor, accountsCursor); 327 addMailboxesToCursor(resultCursor, accountPosition); 328 329 resultCursor.setAccountMailboxInfo(getContext(), mAccountId, mMailboxId); 330 return resultCursor; 331 } 332 333 /** Adds the account list [with extra meta data] to the given matrix cursor */ addAccountsToCursor(CursorWithExtras matrixCursor, Cursor accountCursor)334 private int addAccountsToCursor(CursorWithExtras matrixCursor, Cursor accountCursor) { 335 int accountPosition = UNKNOWN_POSITION; 336 accountCursor.moveToPosition(-1); 337 338 matrixCursor.mAccountCount = accountCursor.getCount(); 339 int totalUnread = 0; 340 while (accountCursor.moveToNext()) { 341 // Add account, with its unread count. 342 final long accountId = accountCursor.getLong(0); 343 final int unread = Mailbox.getUnreadCountByAccountAndMailboxType( 344 mContext, accountId, Mailbox.TYPE_INBOX); 345 final String name = getDisplayName(accountCursor); 346 final String emailAddress = getAccountEmailAddress(accountCursor); 347 addRow(matrixCursor, ROW_TYPE_ACCOUNT, accountId, name, emailAddress, unread, 348 UNKNOWN_POSITION, accountId); 349 totalUnread += unread; 350 if (accountId == mAccountId) { 351 accountPosition = accountCursor.getPosition(); 352 } 353 } 354 // Add "combined view" if more than one account exists 355 final int countAccounts = accountCursor.getCount(); 356 if (countAccounts > 1) { 357 final String accountCount = mContext.getResources().getQuantityString( 358 R.plurals.number_of_accounts, countAccounts, countAccounts); 359 addRow(matrixCursor, ROW_TYPE_ACCOUNT, Account.ACCOUNT_ID_COMBINED_VIEW, 360 getCombinedViewDisplayName(mContext), 361 accountCount, totalUnread, UNKNOWN_POSITION, 362 Account.ACCOUNT_ID_COMBINED_VIEW); 363 364 // Increment the account count for the combined account. 365 matrixCursor.mAccountCount++; 366 } 367 return accountPosition; 368 } 369 370 /** 371 * Adds the recent mailbox list / "show all folders" to the given cursor. 372 * 373 * @param matrixCursor the cursor to add the list to 374 * @param accountPosition the cursor position of the currently selected account 375 */ addMailboxesToCursor(CursorWithExtras matrixCursor, int accountPosition)376 private void addMailboxesToCursor(CursorWithExtras matrixCursor, int accountPosition) { 377 if (mAccountId == Account.NO_ACCOUNT) { 378 return; // Account not selected 379 } 380 if (mAccountId == Account.ACCOUNT_ID_COMBINED_VIEW) { 381 if (!mUseTwoPane) { 382 // TODO We may want a header for this to separate it from the account list 383 addShowAllFoldersRow(matrixCursor, accountPosition); 384 } 385 return; 386 } 387 String emailAddress = null; 388 if (accountPosition != UNKNOWN_POSITION) { 389 matrixCursor.moveToPosition(accountPosition); 390 emailAddress = 391 matrixCursor.getString(matrixCursor.getColumnIndex(Account.EMAIL_ADDRESS)); 392 } 393 RecentMailboxManager mailboxManager = RecentMailboxManager.getInstance(mContext); 394 ArrayList<Long> recentMailboxes = null; 395 if (!mUseTwoPane) { 396 // Do not display recent mailboxes in the account spinner for the two pane view 397 recentMailboxes = mailboxManager.getMostRecent(mAccountId, mUseTwoPane); 398 } 399 final int recentCount = (recentMailboxes == null) ? 0 : recentMailboxes.size(); 400 matrixCursor.mRecentCount = recentCount; 401 402 if (!mUseTwoPane) { 403 // "Recent mailboxes" header 404 addHeaderRow(matrixCursor, mContext.getString( 405 R.string.mailbox_list_account_selector_mailbox_header_fmt, emailAddress)); 406 } 407 408 if (recentCount > 0) { 409 addMailboxRows(matrixCursor, accountPosition, recentMailboxes); 410 } 411 412 if (!mUseTwoPane) { 413 addShowAllFoldersRow(matrixCursor, accountPosition); 414 } 415 } 416 addShowAllFoldersRow(CursorWithExtras matrixCursor, int accountPosition)417 private void addShowAllFoldersRow(CursorWithExtras matrixCursor, int accountPosition) { 418 matrixCursor.mHasShowAllFolders = true; 419 String name = mContext.getString( 420 R.string.mailbox_list_account_selector_show_all_folders); 421 addRow(matrixCursor, ROW_TYPE_MAILBOX, Mailbox.NO_MAILBOX, name, null, 0, 422 accountPosition, mAccountId); 423 } 424 425 426 private static final String[] RECENT_MAILBOX_INFO_PROJECTION = new String[] { 427 MailboxColumns.ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, 428 MailboxColumns.UNREAD_COUNT, MailboxColumns.MESSAGE_COUNT 429 }; 430 addMailboxRows(MatrixCursor matrixCursor, int accountPosition, Collection<Long> mailboxIds)431 private void addMailboxRows(MatrixCursor matrixCursor, int accountPosition, 432 Collection<Long> mailboxIds) { 433 Cursor c = mContext.getContentResolver().query( 434 Mailbox.CONTENT_URI, RECENT_MAILBOX_INFO_PROJECTION, 435 Utility.buildInSelection(MailboxColumns.ID, mailboxIds), null, 436 RecentMailboxManager.RECENT_MAILBOXES_SORT_ORDER); 437 try { 438 c.moveToPosition(-1); 439 while (c.moveToNext()) { 440 addRow(matrixCursor, ROW_TYPE_MAILBOX, 441 c.getLong(c.getColumnIndex(MailboxColumns.ID)), 442 mFolderProperties.getDisplayName(c), null, 443 mFolderProperties.getMessageCount(c), accountPosition, mAccountId); 444 } 445 } finally { 446 c.close(); 447 } 448 } 449 addHeaderRow(MatrixCursor cursor, String name)450 private void addHeaderRow(MatrixCursor cursor, String name) { 451 addRow(cursor, ROW_TYPE_HEADER, 0L, name, null, 0, UNKNOWN_POSITION, 452 Account.NO_ACCOUNT); 453 } 454 455 /** Adds a row to the given cursor */ addRow(MatrixCursor cursor, int rowType, long id, String name, String emailAddress, int messageCount, int listPosition, long accountId)456 private void addRow(MatrixCursor cursor, int rowType, long id, String name, 457 String emailAddress, int messageCount, int listPosition, long accountId) { 458 cursor.newRow() 459 .add(rowType) 460 .add(id) 461 .add(name) 462 .add(emailAddress) 463 .add(messageCount) 464 .add(listPosition) 465 .add(accountId); 466 } 467 } 468 469 /** Cursor with some extra meta data. */ 470 static class CursorWithExtras extends ClosingMatrixCursor { 471 472 /** Number of account elements, including the combined account row. */ 473 private int mAccountCount; 474 /** Number of recent mailbox elements */ 475 private int mRecentCount; 476 private boolean mHasShowAllFolders; 477 478 private boolean mAccountExists; 479 480 /** 481 * Account ID that's loaded. 482 */ 483 private long mAccountId; 484 private String mAccountDisplayName; 485 486 /** 487 * Mailbox ID that's loaded. 488 */ 489 private long mMailboxId; 490 private String mMailboxDisplayName; 491 private int mMailboxMessageCount; 492 493 @VisibleForTesting CursorWithExtras(String[] columnNames, Cursor innerCursor)494 CursorWithExtras(String[] columnNames, Cursor innerCursor) { 495 super(columnNames, innerCursor); 496 } 497 498 private static final String[] ACCOUNT_INFO_PROJECTION = new String[] { 499 AccountColumns.DISPLAY_NAME, 500 }; 501 private static final String[] MAILBOX_INFO_PROJECTION = new String[] { 502 MailboxColumns.ID, MailboxColumns.DISPLAY_NAME, MailboxColumns.TYPE, 503 MailboxColumns.UNREAD_COUNT, MailboxColumns.MESSAGE_COUNT 504 }; 505 506 /** 507 * Set the current account/mailbox info. 508 */ 509 @VisibleForTesting setAccountMailboxInfo(Context context, long accountId, long mailboxId)510 void setAccountMailboxInfo(Context context, long accountId, long mailboxId) { 511 mAccountId = accountId; 512 mMailboxId = mailboxId; 513 514 // Get account info 515 if (accountId == Account.ACCOUNT_ID_COMBINED_VIEW) { 516 // We need to treat ACCOUNT_ID_COMBINED_VIEW specially... 517 mAccountExists = true; 518 mAccountDisplayName = getCombinedViewDisplayName(context); 519 if (mailboxId != Mailbox.NO_MAILBOX) { 520 setCombinedMailboxInfo(context, mailboxId); 521 } 522 return; 523 } 524 525 mAccountDisplayName = Utility.getFirstRowString(context, 526 ContentUris.withAppendedId(Account.CONTENT_URI, accountId), 527 ACCOUNT_INFO_PROJECTION, null, null, null, 0, null); 528 if (mAccountDisplayName == null) { 529 // Account gone! 530 mAccountExists = false; 531 return; 532 } 533 mAccountExists = true; 534 535 // If mailbox not specified, done. 536 if (mMailboxId == Mailbox.NO_MAILBOX) { 537 return; 538 } 539 // Combined mailbox? 540 // Unfortunately this can happen even when account != ACCOUNT_ID_COMBINED_VIEW, 541 // when you open "starred" on 2-pane on non-combined view. 542 if (mMailboxId < 0) { 543 setCombinedMailboxInfo(context, mailboxId); 544 return; 545 } 546 547 // Get mailbox info 548 final ContentResolver r = context.getContentResolver(); 549 final Cursor mailboxCursor = r.query( 550 ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId), 551 MAILBOX_INFO_PROJECTION, null, null, null); 552 try { 553 if (mailboxCursor.moveToFirst()) { 554 final FolderProperties fp = FolderProperties.getInstance(context); 555 mMailboxDisplayName = fp.getDisplayName(mailboxCursor); 556 mMailboxMessageCount = fp.getMessageCount(mailboxCursor); 557 } 558 } finally { 559 mailboxCursor.close(); 560 } 561 } 562 setCombinedMailboxInfo(Context context, long mailboxId)563 private void setCombinedMailboxInfo(Context context, long mailboxId) { 564 Preconditions.checkState(mailboxId < -1, "Not combined mailbox"); 565 mMailboxDisplayName = FolderProperties.getInstance(context) 566 .getCombinedMailboxName(mMailboxId); 567 568 mMailboxMessageCount = FolderProperties.getMessageCountForCombinedMailbox( 569 context, mailboxId); 570 } 571 572 /** 573 * Returns the cursor position of the item with the given ID. Or {@link #UNKNOWN_POSITION} 574 * if the given ID does not exist. 575 */ 576 int getPosition(long id) { 577 moveToPosition(-1); 578 while(moveToNext()) { 579 if (id == getId(this)) { 580 return getPosition(); 581 } 582 } 583 return UNKNOWN_POSITION; 584 } 585 586 public int getAccountCount() { 587 return mAccountCount; 588 } 589 590 @VisibleForTesting 591 public int getRecentMailboxCount() { 592 return mRecentCount; 593 } 594 595 /** 596 * @return true if the cursor has more than one selectable item so we should enable the 597 * spinner. 598 */ 599 public boolean shouldEnableSpinner() { 600 return mHasShowAllFolders || (mAccountCount + mRecentCount > 1); 601 } 602 getAccountId()603 public long getAccountId() { 604 return mAccountId; 605 } 606 getAccountDisplayName()607 public String getAccountDisplayName() { 608 return mAccountDisplayName; 609 } 610 611 @VisibleForTesting getMailboxId()612 public long getMailboxId() { 613 return mMailboxId; 614 } 615 getMailboxDisplayName()616 public String getMailboxDisplayName() { 617 return mMailboxDisplayName; 618 } 619 getMailboxMessageCount()620 public int getMailboxMessageCount() { 621 return mMailboxMessageCount; 622 } 623 624 /** 625 * @return {@code true} if the specified accuont exists. 626 */ accountExists()627 public boolean accountExists() { 628 return mAccountExists; 629 } 630 } 631 } 632