Exemple #1
0
  @Override
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (mActivity == null) {
      return false;
    }

    final Uri uri = Uri.parse(url);
    if (Utils.divertMailtoUri(mActivity, uri, mAccount)) {
      return true;
    }

    final Intent intent;
    if (mAccount != null && !Utils.isEmpty(mAccount.viewIntentProxyUri)) {
      intent = generateProxyIntent(uri);
    } else {
      intent = new Intent(Intent.ACTION_VIEW, uri);
      intent.putExtra(Browser.EXTRA_APPLICATION_ID, mActivity.getPackageName());
      intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
    }

    boolean result = false;
    try {
      intent.setFlags(
          Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | Intent.FLAG_ACTIVITY_NO_ANIMATION);
      mActivity.startActivity(intent);
      result = true;
    } catch (ActivityNotFoundException ex) {
      // If no application can handle the URL, assume that the
      // caller can handle it.
    }

    return result;
  }
  /**
   * @param view The view to be dismissed
   * @param velocity The desired pixels/second speed at which the view should move
   */
  private void dismissChild(final SwipeableItemView view, float velocity) {
    final View animView = mCurrView.getSwipeableView().getView();
    final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
    float newPos = determinePos(animView, velocity);
    int duration = determineDuration(animView, newPos, velocity);

    Utils.enableHardwareLayer(animView);
    ObjectAnimator anim = createDismissAnimation(animView, newPos, duration);
    anim.addListener(
        new AnimatorListenerAdapter() {
          @Override
          public void onAnimationEnd(Animator animation) {
            mCallback.onChildDismissed(mCurrView);
            animView.setLayerType(View.LAYER_TYPE_NONE, null);
          }
        });
    anim.addUpdateListener(
        new AnimatorUpdateListener() {
          @Override
          public void onAnimationUpdate(ValueAnimator animation) {
            if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
              animView.setAlpha(getAlphaForOffset(animView));
            }
            invalidateGlobalRegion(animView);
          }
        });
    anim.start();
  }
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    if (!isUserVisible()) {
      // Unclear how this is happening. Current theory is that this fragment was scheduled
      // to be removed, but the remove transaction failed. When the Activity is later
      // restored, the FragmentManager restores this fragment, but Fragment.mMenuVisible is
      // stuck at its initial value (true), which makes this zombie fragment eligible for
      // menu item clicks.
      //
      // Work around this by relying on the (properly restored) extra user visible hint.
      LogUtils.e(
          LOG_TAG, "ACVF ignoring onOptionsItemSelected b/c userVisibleHint is false. f=%s", this);
      if (LogUtils.isLoggable(LOG_TAG, LogUtils.DEBUG)) {
        LogUtils.e(LOG_TAG, Utils.dumpFragment(this)); // the dump has '%' chars in it...
      }
      return false;
    }

    boolean handled = false;
    final int itemId = item.getItemId();
    if (itemId == R.id.inside_conversation_unread) {
      markUnread();
      handled = true;
    } else if (itemId == R.id.show_original) {
      showUntransformedConversation();
      handled = true;
    }
    return handled;
  }
 /**
  * Get the desired dimensions and scale for the bitmap to be placed in the location corresponding
  * to id. Caller must allocate the Dimensions object.
  *
  * @param key
  * @param outDim a {@link ImageCanvas.Dimensions} object to write results into
  */
 @Override
 public void getDesiredDimensions(Object key, Dimensions outDim) {
   Utils.traceBeginSection("get desired dimensions");
   int w = 0, h = 0;
   float scale = 0;
   final Integer pos = mDivisionMap.get(transformKeyToDivisionId(key));
   if (pos != null && pos >= 0) {
     final int size = mDivisionMap.size();
     switch (size) {
       case 0:
         break;
       case 1:
         w = mWidth;
         h = mHeight;
         scale = Dimensions.SCALE_ONE;
         break;
       case 2:
         w = mWidth / 2;
         h = mHeight;
         scale = Dimensions.SCALE_HALF;
         break;
       case 3:
         switch (pos) {
           case 0:
             w = mWidth / 2;
             h = mHeight;
             scale = Dimensions.SCALE_HALF;
             break;
           default:
             w = mWidth / 2;
             h = mHeight / 2;
             scale = Dimensions.SCALE_QUARTER;
         }
         break;
       case 4:
         w = mWidth / 2;
         h = mHeight / 2;
         scale = Dimensions.SCALE_QUARTER;
         break;
     }
   }
   outDim.width = w;
   outDim.height = h;
   outDim.scale = scale;
   Utils.traceEndSection();
 }
Exemple #5
0
 public String toString() {
   if ((this.mName != null) && (!this.mName.equals(this.mAddress))) {
     if (this.mName.matches(".*[\\(\\)<>@,;:\\\\\".\\[\\]].*"))
       return Utils.ensureQuotedString(this.mName) + " <" + this.mAddress + ">";
     return this.mName + " <" + this.mAddress + ">";
   }
   return this.mAddress;
 }
 public void setQuotedText(int action, Message refMessage, boolean allow) {
   setVisibility(View.VISIBLE);
   String htmlText = getHtmlText(refMessage);
   StringBuilder quotedText = new StringBuilder();
   DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT);
   Date date = new Date(refMessage.dateReceivedMs);
   Resources resources = getContext().getResources();
   if (action == ComposeActivity.REPLY || action == ComposeActivity.REPLY_ALL) {
     quotedText.append(sQuoteBegin);
     quotedText.append(
         String.format(
             resources.getString(R.string.reply_attribution),
             dateFormat.format(date),
             Utils.cleanUpString(refMessage.getFrom(), true)));
     quotedText.append(HEADER_SEPARATOR);
     quotedText.append(BLOCKQUOTE_BEGIN);
     quotedText.append(htmlText);
     quotedText.append(BLOCKQUOTE_END);
     quotedText.append(QUOTE_END);
   } else if (action == ComposeActivity.FORWARD) {
     quotedText.append(sQuoteBegin);
     quotedText.append(
         String.format(
             resources.getString(R.string.forward_attribution),
             Utils.cleanUpString(refMessage.getFrom(), true /* remove empty quotes */),
             dateFormat.format(date),
             Utils.cleanUpString(refMessage.subject, false /* don't remove empty quotes */),
             Utils.cleanUpString(refMessage.getTo(), true)));
     String ccAddresses = refMessage.getCc();
     quotedText.append(
         String.format(
             resources.getString(R.string.cc_attribution),
             Utils.cleanUpString(ccAddresses, true /* remove empty quotes */)));
     quotedText.append(HEADER_SEPARATOR);
     quotedText.append(BLOCKQUOTE_BEGIN);
     quotedText.append(htmlText);
     quotedText.append(BLOCKQUOTE_END);
     quotedText.append(QUOTE_END);
   }
   setQuotedText(quotedText);
   allowQuotedText(allow);
   // If there is quoted text, we always allow respond inline, since this
   // may be a forward.
   allowRespondInline(true);
 }
 /** M: Don't show feedback menu if no feedback Uri is set */
 @Override
 public void onPrepareOptionsMenu(Menu menu) {
   super.onPrepareOptionsMenu(menu);
   MenuItem feedBackMenuItem = menu.findItem(R.id.feedback_menu_item);
   if (feedBackMenuItem != null) {
     Uri feedBackUri = Utils.getValidUri(getString(R.string.email_feedback_uri));
     // We only want to enable the feedback menu item, if there is a valid feedback uri
     feedBackMenuItem.setVisible(!Uri.EMPTY.equals(feedBackUri));
   }
 }
  /**
   * Set the width and height of the canvas.
   *
   * @param width
   * @param height
   */
  public void setDimensions(int width, int height) {
    Utils.traceBeginSection("set dimensions");
    if (mWidth == width && mHeight == height) {
      Utils.traceEndSection();
      return;
    }

    mWidth = width;
    mHeight = height;

    mDividedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mDividedBitmap);

    for (int i = 0; i < getDivisionCount(); i++) {
      mDivisionImages.set(i, null);
    }
    mBitmapValid = false;
    Utils.traceEndSection();
  }
 @Override
 public void onPrepareOptionsMenu(Menu menu) {
   // Only show option if we support message transforms and message has been transformed.
   Utils.setMenuItemVisibility(
       menu,
       R.id.show_original,
       supportsMessageTransforms()
           && mHasConversationBeenTransformed
           && !mHasConversationTransformBeenReverted);
 }
 private void respondInline() {
   // Copy the text in the quoted message to the body of the
   // message after stripping the html.
   final String plainText = Utils.convertHtmlToPlainText(getQuotedText().toString());
   if (mRespondInlineListener != null) {
     mRespondInlineListener.onRespondInline("\n" + plainText);
   }
   // Set quoted text to unchecked and not visible.
   updateCheckedState(false);
   mRespondInlineButton.setVisibility(View.GONE);
   // Hide everything to do with quoted text.
   View quotedTextView = findViewById(R.id.quoted_text_area);
   if (quotedTextView != null) {
     quotedTextView.setVisibility(View.GONE);
   }
 }
  /**
   * Uses the current state to update the current folder {@link #mFolder} and the current account
   * {@link #mAccount} shown in the actionbar. Also updates the actionbar subtitle to momentarily
   * display the unread count if it has changed.
   *
   * @param folderChanged true if folder changed in terms of URI
   */
  private void setFolderAndAccount(final boolean folderChanged) {
    // Very little can be done if the actionbar or activity is null.
    if (mActionBar == null || mActivity == null) {
      return;
    }
    if (ViewMode.isWaitingForSync(mMode)) {
      // Account is not synced: clear title and update the subtitle.
      setTitle("");
      removeUnreadCount(true);
      return;
    }
    // Check if we should be changing the actionbar at all, and back off if not.
    final boolean isShowingFolder = mIsOnTablet || ViewMode.isListMode(mMode);
    if (!isShowingFolder) {
      // It isn't necessary to set the title in this case, as the title view will
      // be hidden
      return;
    }
    if (mFolder == null) {
      // Clear the action bar title.  We don't want the app name to be shown while
      // waiting for the folder query to finish
      setTitle("");
      return;
    }
    setTitle(mFolder.name);

    final int folderUnreadCount = mFolder.isUnreadCountHidden() ? 0 : mFolder.unreadCount;
    // The user shouldn't see "999+ unread messages", and then a short while later: "999+
    // unread messages". So we set our unread count just past the limit. This way we can
    // change the subtitle the first time around but not for subsequent changes as far as the
    // unread count remains over the limit.
    final int toDisplay =
        (folderUnreadCount > UNREAD_LIMIT) ? (UNREAD_LIMIT + 1) : folderUnreadCount;
    if ((mUnreadCount != toDisplay || folderChanged) && toDisplay != 0) {
      setSubtitle(Utils.getUnreadMessageString(mActivity.getApplicationContext(), toDisplay));
    }
    // Schedule a removal of unread count for the future, if there isn't one already. If the
    // unread count dropped to zero, remove it and show the account name right away.
    removeUnreadCount(toDisplay == 0);
    // Remember the new value for the next run
    mUnreadCount = toDisplay;
  }
 public void viewAttachment() {
   if (this.mAttachment.contentUri == null) {
     LogUtils.e(LOG_TAG, "viewAttachment with null content uri", new Object[0]);
     return;
   }
   Intent localIntent = new Intent("android.intent.action.VIEW");
   localIntent.setFlags(524289);
   Utils.setIntentDataAndTypeAndNormalize(
       localIntent, this.mAttachment.contentUri, this.mAttachment.contentType);
   try {
     getContext().startActivity(localIntent);
     return;
   } catch (ActivityNotFoundException localActivityNotFoundException) {
     LogUtils.e(
         LOG_TAG,
         localActivityNotFoundException,
         "Couldn't find Activity for intent",
         new Object[0]);
   }
 }
  public QuotedTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs);
    LayoutInflater factory = LayoutInflater.from(context);
    factory.inflate(R.layout.quoted_text, this);

    mQuotedTextWebView = (WebView) findViewById(R.id.quoted_text_web_view);
    Utils.restrictWebView(mQuotedTextWebView);
    WebSettings settings = mQuotedTextWebView.getSettings();
    settings.setBlockNetworkLoads(true);

    mShowHideCheckBox = (CheckBox) findViewById(R.id.hide_quoted_text);
    mShowHideCheckBox.setChecked(true);
    mShowHideCheckBox.setOnClickListener(this);
    sQuoteBegin = context.getResources().getString(R.string.quote_begin);
    findViewById(R.id.hide_quoted_text_label).setOnClickListener(this);

    mRespondInlineButton = (Button) findViewById(R.id.respond_inline_button);
    if (mRespondInlineButton != null) {
      mRespondInlineButton.setEnabled(false);
    }
  }
 public MailActionBarView(Context context, AttributeSet attrs, int defStyle) {
   super(context, attrs, defStyle);
   final Resources r = getResources();
   mIsOnTablet = Utils.useTabletUI(r);
   UNREAD_LIMIT = r.getInteger(R.integer.maxUnreadCount);
 }
 private void addOrClearDivisionImage(Bitmap b, Object key) {
   Utils.traceBeginSection("add or clear division image");
   final Integer pos = mDivisionMap.get(transformKeyToDivisionId(key));
   if (pos != null && pos >= 0) {
     mDivisionImages.set(pos, b);
     boolean complete = false;
     final int width = mWidth;
     final int height = mHeight;
     // Different layouts depending on count.
     final int size = mDivisionMap.size();
     switch (size) {
       case 0:
         // Do nothing.
         break;
       case 1:
         // Draw the bitmap filling the entire canvas.
         draw(mDivisionImages.get(0), 0, 0, width, height);
         complete = true;
         break;
       case 2:
         // Draw 2 bitmaps split vertically down the middle
         switch (pos) {
           case 0:
             draw(mDivisionImages.get(0), 0, 0, width / 2, height);
             break;
           case 1:
             draw(mDivisionImages.get(1), width / 2, 0, width, height);
             break;
         }
         complete =
             mDivisionImages.get(0) != null && mDivisionImages.get(1) != null
                 || isPartialBitmapComplete();
         if (complete) {
           // Draw dividers
           drawVerticalDivider(width, height);
         }
         break;
       case 3:
         // Draw 3 bitmaps: the first takes up all vertical
         // space, the 2nd and 3rd are stacked in the second vertical
         // position.
         switch (pos) {
           case 0:
             draw(mDivisionImages.get(0), 0, 0, width / 2, height);
             break;
           case 1:
             draw(mDivisionImages.get(1), width / 2, 0, width, height / 2);
             break;
           case 2:
             draw(mDivisionImages.get(2), width / 2, height / 2, width, height);
             break;
         }
         complete =
             mDivisionImages.get(0) != null
                     && mDivisionImages.get(1) != null
                     && mDivisionImages.get(2) != null
                 || isPartialBitmapComplete();
         if (complete) {
           // Draw dividers
           drawVerticalDivider(width, height);
           drawHorizontalDivider(width / 2, height / 2, width, height / 2);
         }
         break;
       default:
         // Draw all 4 bitmaps in a grid
         switch (pos) {
           case 0:
             draw(mDivisionImages.get(0), 0, 0, width / 2, height / 2);
             break;
           case 1:
             draw(mDivisionImages.get(1), width / 2, 0, width, height / 2);
             break;
           case 2:
             draw(mDivisionImages.get(2), 0, height / 2, width / 2, height);
             break;
           case 3:
             draw(mDivisionImages.get(3), width / 2, height / 2, width, height);
             break;
         }
         complete =
             mDivisionImages.get(0) != null
                     && mDivisionImages.get(1) != null
                     && mDivisionImages.get(2) != null
                     && mDivisionImages.get(3) != null
                 || isPartialBitmapComplete();
         if (complete) {
           // Draw dividers
           drawVerticalDivider(width, height);
           drawHorizontalDivider(0, height / 2, width, height / 2);
         }
         break;
     }
     // Create the new image bitmap.
     if (complete) {
       mBitmapValid = true;
       mCallback.invalidate();
     }
   }
   Utils.traceEndSection();
 }
 public ConversationListFooterView(Context context, AttributeSet attrs) {
   super(context, attrs);
   mTabletDevice = Utils.useTabletUI(context.getResources());
 }
  /** Update the view to reflect the new folder status. */
  public boolean updateStatus(final ConversationCursor cursor) {
    if (cursor == null) {
      updateLoadingStatus(true);
      return true;
    }
    boolean showFooter = true;
    final Bundle extras = cursor.getExtras();
    final int cursorStatus = extras.getInt(UIProvider.CursorExtraKeys.EXTRA_STATUS);
    mErrorStatus =
        extras.containsKey(UIProvider.CursorExtraKeys.EXTRA_ERROR)
            ? extras.getInt(UIProvider.CursorExtraKeys.EXTRA_ERROR)
            : UIProvider.LastSyncResult.SUCCESS;
    final int totalCount = extras.getInt(UIProvider.CursorExtraKeys.EXTRA_TOTAL_COUNT);
    /// M: Get the value from extra
    final boolean allMessagesLoadFinish =
        extras.getBoolean(UIProvider.CursorExtraKeys.EXTRA_MESSAGES_LOAD_FINISH, false);
    if (UIProvider.CursorStatus.isWaitingForResults(cursorStatus)) {
      updateLoadingStatus(true);
    } else if (mErrorStatus != UIProvider.LastSyncResult.SUCCESS) {
      mNetworkError.setVisibility(View.VISIBLE);
      mErrorText.setText(Utils.getSyncStatusText(getContext(), mErrorStatus));
      mLoading.setVisibility(View.GONE);
      mLoadMore.setVisibility(View.GONE);
      // Only show the "Retry" button for I/O errors; it won't help for
      // internal errors.
      mErrorActionButton.setVisibility(
          mErrorStatus != UIProvider.LastSyncResult.SECURITY_ERROR ? View.VISIBLE : View.GONE);

      final int actionTextResourceId;
      switch (mErrorStatus) {
        case UIProvider.LastSyncResult.CONNECTION_ERROR:
          actionTextResourceId = R.string.retry;
          break;
        case UIProvider.LastSyncResult.AUTH_ERROR:
          actionTextResourceId = R.string.signin;
          break;
        case UIProvider.LastSyncResult.SECURITY_ERROR:
          actionTextResourceId = R.string.retry;
          mNetworkError.setVisibility(View.GONE);
          break; // Currently we do nothing for security errors.
        case UIProvider.LastSyncResult.STORAGE_ERROR:
          actionTextResourceId = R.string.info;
          break;
        case UIProvider.LastSyncResult.INTERNAL_ERROR:
          actionTextResourceId = R.string.report;
          break;
        default:
          actionTextResourceId = R.string.retry;
          mNetworkError.setVisibility(View.GONE);
          break;
      }
      mErrorActionButton.setText(actionTextResourceId);

    } else if (mLoadMoreUri != null
        && cursor.getCount() < totalCount
        /**
         * M: filter some dirty update callback, default when cursor count little than total count.
         * load more view will show, in fact in the initial step of remote search the loader
         * complete result is 0 before run search on server, which will cause loading status
         * stopped. It make user confused, 'It should loading instead of load more' @}
         */
        && cursor.getCount() > 0) {
      /** @} */
      LogUtils.d(
          LogTag.getLogTag(),
          " LoadMore finished folder [%s], totalCount %d, cursor count %d",
          mLoadMoreUri,
          totalCount,
          cursor.getCount());
      if (allMessagesLoadFinish) {
        /// M: When all messages load finish, load more do not need to display.
        showFooter = false;
      } else {
        updateLoadingStatus(false);
      }
    } else {
      showFooter = false;
    }
    return showFooter;
  }
  // We need to do this here instead of in the fragment
  public void setConversationModeOptions(Menu menu) {
    if (mCurrentConversation == null) {
      return;
    }
    final boolean showMarkImportant = !mCurrentConversation.isImportant();
    Utils.setMenuItemVisibility(
        menu,
        R.id.mark_important,
        showMarkImportant
            && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
    Utils.setMenuItemVisibility(
        menu,
        R.id.mark_not_important,
        !showMarkImportant
            && mAccount.supportsCapability(UIProvider.AccountCapabilities.MARK_IMPORTANT));
    final boolean showDelete =
        mFolder != null && mFolder.supportsCapability(UIProvider.FolderCapabilities.DELETE);
    Utils.setMenuItemVisibility(menu, R.id.delete, showDelete);
    // We only want to show the discard drafts menu item if we are not showing the delete menu
    // item, and the current folder is a draft folder and the account supports discarding
    // drafts for a conversation
    final boolean showDiscardDrafts =
        !showDelete
            && mFolder != null
            && mFolder.isDraft()
            && mAccount.supportsCapability(AccountCapabilities.DISCARD_CONVERSATION_DRAFTS);
    Utils.setMenuItemVisibility(menu, R.id.discard_drafts, showDiscardDrafts);
    final boolean archiveVisible =
        mAccount.supportsCapability(AccountCapabilities.ARCHIVE)
            && mFolder != null
            && mFolder.supportsCapability(FolderCapabilities.ARCHIVE)
            && !mFolder.isTrash();
    Utils.setMenuItemVisibility(menu, R.id.archive, archiveVisible);
    Utils.setMenuItemVisibility(
        menu,
        R.id.remove_folder,
        !archiveVisible
            && mFolder != null
            && mFolder.supportsCapability(FolderCapabilities.CAN_ACCEPT_MOVED_MESSAGES)
            && !mFolder.isProviderFolder()
            && mAccount.supportsCapability(AccountCapabilities.ARCHIVE));
    Utils.setMenuItemVisibility(
        menu,
        R.id.move_to,
        mFolder != null
            && mFolder.supportsCapability(FolderCapabilities.ALLOWS_REMOVE_CONVERSATION));
    Utils.setMenuItemVisibility(
        menu,
        R.id.move_to_inbox,
        mFolder != null && mFolder.supportsCapability(FolderCapabilities.ALLOWS_MOVE_TO_INBOX));

    final MenuItem removeFolder = menu.findItem(R.id.remove_folder);
    if (mFolder != null && removeFolder != null) {
      removeFolder.setTitle(
          mActivity.getApplicationContext().getString(R.string.remove_folder, mFolder.name));
    }
    Utils.setMenuItemVisibility(
        menu,
        R.id.report_spam,
        mAccount.supportsCapability(AccountCapabilities.REPORT_SPAM)
            && mFolder != null
            && mFolder.supportsCapability(FolderCapabilities.REPORT_SPAM)
            && !mCurrentConversation.spam);
    Utils.setMenuItemVisibility(
        menu,
        R.id.mark_not_spam,
        mAccount.supportsCapability(AccountCapabilities.REPORT_SPAM)
            && mFolder != null
            && mFolder.supportsCapability(FolderCapabilities.MARK_NOT_SPAM)
            && mCurrentConversation.spam);
    Utils.setMenuItemVisibility(
        menu,
        R.id.report_phishing,
        mAccount.supportsCapability(AccountCapabilities.REPORT_PHISHING)
            && mFolder != null
            && mFolder.supportsCapability(FolderCapabilities.REPORT_PHISHING)
            && !mCurrentConversation.phishing);
    Utils.setMenuItemVisibility(
        menu,
        R.id.mute,
        mAccount.supportsCapability(AccountCapabilities.MUTE)
            && mFolder != null
            && mFolder.supportsCapability(FolderCapabilities.DESTRUCTIVE_MUTE)
            && !mCurrentConversation.muted);
  }
  public boolean onPrepareOptionsMenu(Menu menu) {
    // We start out with every option enabled. Based on the current view, we disable actions
    // that are possible.
    LogUtils.d(LOG_TAG, "ActionBarView.onPrepareOptionsMenu().");

    if (mHelpItem != null) {
      mHelpItem.setVisible(
          mAccount != null && mAccount.supportsCapability(AccountCapabilities.HELP_CONTENT));
    }
    if (mSendFeedbackItem != null) {
      mSendFeedbackItem.setVisible(
          mAccount != null && mAccount.supportsCapability(AccountCapabilities.SEND_FEEDBACK));
    }
    if (mController.shouldHideMenuItems()) {
      // Shortcut: hide all remaining menu items if the drawer is shown
      final int size = menu.size();

      for (int i = 0; i < size; i++) {
        final MenuItem item = menu.getItem(i);
        final int id = item.getItemId();
        if (id != R.id.settings
            && id != R.id.feedback_menu_item
            && id != R.id.help_info_menu_item) {
          item.setVisible(false);
        }
      }
      return false;
    }

    if (mRefreshItem != null) {
      // See b/11158759
      // Disable refresh on drafts folders.
      mRefreshItem.setVisible(
          mFolder != null
              && !mFolder.isDraft()
              && !mFolder.supportsCapability(FolderCapabilities.IS_VIRTUAL));
    }

    if (mFolderSettingsItem != null) {
      mFolderSettingsItem.setVisible(
          mFolder != null && mFolder.supportsCapability(FolderCapabilities.SUPPORTS_SETTINGS));
    }
    if (mEmptyTrashItem != null) {
      mEmptyTrashItem.setVisible(
          mAccount != null
              && mFolder != null
              && mAccount.supportsCapability(AccountCapabilities.EMPTY_TRASH)
              && mFolder.isTrash()
              && mFolder.totalCount > 0);
    }
    if (mEmptySpamItem != null) {
      mEmptySpamItem.setVisible(
          mAccount != null
              && mFolder != null
              && mAccount.supportsCapability(AccountCapabilities.EMPTY_SPAM)
              && mFolder.isType(FolderType.SPAM)
              && mFolder.totalCount > 0);
    }

    switch (mMode) {
      case ViewMode.CONVERSATION:
      case ViewMode.SEARCH_RESULTS_CONVERSATION:
        // We update the ActionBar options when we are entering conversation view because
        // waiting for the AbstractConversationViewFragment to do it causes duplicate icons
        // to show up during the time between the conversation is selected and the fragment
        // is added.
        setConversationModeOptions(menu);
        // We want to use the user's preferred menu items here
        final Resources resources = getResources();
        final int maxItems = resources.getInteger(R.integer.actionbar_max_items);
        final int hiddenItems =
            resources.getInteger(R.integer.actionbar_hidden_non_cab_items_no_physical_button);
        final int totalItems =
            maxItems
                - (ViewConfiguration.get(getContext()).hasPermanentMenuKey() ? 0 : hiddenItems);
        reorderMenu(getContext(), mAccount, menu, totalItems);
        break;
      case ViewMode.CONVERSATION_LIST:
        // Show compose and search based on the account
        // The only option that needs to be disabled is search
        Utils.setMenuItemVisibility(
            menu,
            R.id.search,
            mAccount.supportsCapability(AccountCapabilities.FOLDER_SERVER_SEARCH));
        break;
      case ViewMode.SEARCH_RESULTS_LIST:
        // Hide compose and search
        Utils.setMenuItemVisibility(menu, R.id.compose, false);
        Utils.setMenuItemVisibility(menu, R.id.search, false);
        break;
    }

    return false;
  }