| Index: content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
 | 
| diff --git a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
 | 
| index b8bf0efad5cf23d3dfacf3f6fc60184db1c8d8ac..157f6851950cdf036966292c7cc84734e06a0a07 100644
 | 
| --- a/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
 | 
| +++ b/content/public/android/java/src/org/chromium/content/browser/SelectionPopupController.java
 | 
| @@ -118,10 +118,6 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|      private boolean mUnselectAllOnDismiss;
 | 
|      private String mLastSelectedText;
 | 
|  
 | 
| -    // Tracks whether a selection is currently active.  When applied to selected text, indicates
 | 
| -    // whether the last selected text is still highlighted.
 | 
| -    private boolean mHasSelection;
 | 
| -
 | 
|      // Lazily created paste popup menu, triggered either via long press in an
 | 
|      // editable region or from tapping the insertion handle.
 | 
|      private PastePopupMenu mPastePopupMenu;
 | 
| @@ -176,6 +172,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|          mSelectionClient =
 | 
|                  SmartSelectionClient.create(new SmartSelectionCallback(), window, webContents);
 | 
|  
 | 
| +        mLastSelectedText = "";
 | 
|          // TODO(timav): Use android.R.id.textAssist for the Assist item id once we switch to
 | 
|          // Android O SDK and remove |mAssistMenuItemId|.
 | 
|          if (BuildInfo.isAtLeastO()) {
 | 
| @@ -223,6 +220,31 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|          mAllowedMenuItems = allowedMenuItems;
 | 
|      }
 | 
|  
 | 
| +    public void showSelectionMenu(int left, int top, int right, int bottom, boolean isEditable,
 | 
| +            boolean isPasswordType, String selectionText, boolean canSelectAll,
 | 
| +            boolean canRichlyEdit, boolean shouldSuggest) {
 | 
| +        mSelectionRect.set(left, top, right, bottom);
 | 
| +        mEditable = isEditable;
 | 
| +        mLastSelectedText = selectionText;
 | 
| +        mIsPasswordType = isPasswordType;
 | 
| +        mCanSelectAllForPastePopup = canSelectAll;
 | 
| +        mCanEditRichlyForPastePopup = canRichlyEdit;
 | 
| +        mUnselectAllOnDismiss = true;
 | 
| +        if (hasSelection()) {
 | 
| +            if (mSelectionClient != null
 | 
| +                    && mSelectionClient.requestSelectionPopupUpdates(shouldSuggest)) {
 | 
| +                // Rely on |mSelectionClient| sending a classification request and the request
 | 
| +                // always calling onClassified() callback.
 | 
| +                mPendingShowActionMode = true;
 | 
| +            } else {
 | 
| +                showActionModeOrClearOnFailure();
 | 
| +            }
 | 
| +
 | 
| +        } else {
 | 
| +            createAndShowPastePopup();
 | 
| +        }
 | 
| +    }
 | 
| +
 | 
|      /**
 | 
|       * Show (activate) android action mode by starting it.
 | 
|       *
 | 
| @@ -233,7 +255,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|      public void showActionModeOrClearOnFailure() {
 | 
|          mPendingShowActionMode = false;
 | 
|  
 | 
| -        if (!isActionModeSupported() || !mHasSelection) return;
 | 
| +        if (!isActionModeSupported() || !hasSelection()) return;
 | 
|  
 | 
|          // Just refresh the view if action mode already exists.
 | 
|          if (isActionModeValid()) {
 | 
| @@ -268,17 +290,13 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|          return actionMode;
 | 
|      }
 | 
|  
 | 
| -    void createAndShowPastePopup(
 | 
| -            int left, int top, int right, int bottom, boolean canSelectAll, boolean canEditRichly) {
 | 
| +    private void createAndShowPastePopup() {
 | 
|          if (mView.getParent() == null || mView.getVisibility() != View.VISIBLE) {
 | 
|              return;
 | 
|          }
 | 
|  
 | 
|          if (!supportsFloatingActionMode() && !canPaste()) return;
 | 
|          destroyPastePopup();
 | 
| -        mSelectionRect.set(left, top, right, bottom);
 | 
| -        mCanSelectAllForPastePopup = canSelectAll;
 | 
| -        mCanEditRichlyForPastePopup = canEditRichly;
 | 
|          PastePopupMenuDelegate delegate = new PastePopupMenuDelegate() {
 | 
|              @Override
 | 
|              public void paste() {
 | 
| @@ -493,7 +511,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|              descriptor.removeItem(R.id.select_action_menu_paste);
 | 
|          }
 | 
|  
 | 
| -        if (isInsertion()) {
 | 
| +        if (!hasSelection()) {
 | 
|              descriptor.removeItem(R.id.select_action_menu_select_all);
 | 
|              descriptor.removeItem(R.id.select_action_menu_cut);
 | 
|              descriptor.removeItem(R.id.select_action_menu_copy);
 | 
| @@ -730,8 +748,6 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|      void selectAll() {
 | 
|          mWebContents.selectAll();
 | 
|          mClassificationResult = null;
 | 
| -        if (needsActionMenuUpdate()) showActionModeOrClearOnFailure();
 | 
| -
 | 
|          // Even though the above statement logged a SelectAll user action, we want to
 | 
|          // track whether the focus was in an editable field, so log that too.
 | 
|          if (isSelectionEditable()) {
 | 
| @@ -908,7 +924,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|          if (mWebContents == null || resultCode != Activity.RESULT_OK || data == null) return;
 | 
|  
 | 
|          // Do not handle the result if no text is selected or current selection is not editable.
 | 
| -        if (!mHasSelection || !isSelectionEditable()) return;
 | 
| +        if (!hasSelection() || !isSelectionEditable()) return;
 | 
|  
 | 
|          CharSequence result = data.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT);
 | 
|          if (result != null) {
 | 
| @@ -919,7 +935,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|      }
 | 
|  
 | 
|      void restoreSelectionPopupsIfNecessary() {
 | 
| -        if (mHasSelection && !isActionModeValid()) {
 | 
| +        if (hasSelection() && !isActionModeValid()) {
 | 
|              showActionModeOrClearOnFailure();
 | 
|          }
 | 
|      }
 | 
| @@ -933,17 +949,6 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|          if (top == bottom) ++bottom;
 | 
|          switch (eventType) {
 | 
|              case SelectionEventType.SELECTION_HANDLES_SHOWN:
 | 
| -                mSelectionRect.set(left, top, right, bottom);
 | 
| -                mHasSelection = true;
 | 
| -                mUnselectAllOnDismiss = true;
 | 
| -                if (mSelectionClient != null
 | 
| -                        && mSelectionClient.requestSelectionPopupUpdates(true /* suggest */)) {
 | 
| -                    // Rely on |mSelectionClient| sending a classification request and the request
 | 
| -                    // always calling onClassified() callback.
 | 
| -                    mPendingShowActionMode = true;
 | 
| -                } else {
 | 
| -                    showActionModeOrClearOnFailure();
 | 
| -                }
 | 
|                  break;
 | 
|  
 | 
|              case SelectionEventType.SELECTION_HANDLES_MOVED:
 | 
| @@ -956,7 +961,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|                  break;
 | 
|  
 | 
|              case SelectionEventType.SELECTION_HANDLES_CLEARED:
 | 
| -                mHasSelection = false;
 | 
| +                mLastSelectedText = "";
 | 
|                  mUnselectAllOnDismiss = false;
 | 
|                  mSelectionRect.setEmpty();
 | 
|                  if (mSelectionClient != null) mSelectionClient.cancelAllRequests();
 | 
| @@ -968,13 +973,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|                  break;
 | 
|  
 | 
|              case SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED:
 | 
| -                if (mSelectionClient != null
 | 
| -                        && mSelectionClient.requestSelectionPopupUpdates(false /* suggest */)) {
 | 
| -                    // Rely on |mSelectionClient| sending a classification request and the request
 | 
| -                    // always calling onClassified() callback.
 | 
| -                } else {
 | 
| -                    hideActionMode(false);
 | 
| -                }
 | 
| +                mWebContents.showContextMenuAtTouchHandle(left, bottom);
 | 
|                  break;
 | 
|  
 | 
|              case SelectionEventType.INSERTION_HANDLE_SHOWN:
 | 
| @@ -1096,12 +1095,12 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|       */
 | 
|      @VisibleForTesting
 | 
|      public boolean hasSelection() {
 | 
| -        return mHasSelection;
 | 
| +        return mLastSelectedText.length() != 0;
 | 
|      }
 | 
|  
 | 
|      @Override
 | 
|      public String getSelectedText() {
 | 
| -        return mHasSelection ? mLastSelectedText : "";
 | 
| +        return mLastSelectedText;
 | 
|      }
 | 
|  
 | 
|      private boolean isShareAvailable() {
 | 
| @@ -1142,7 +1141,7 @@ public class SelectionPopupController extends ActionModeCallbackHelper {
 | 
|          @Override
 | 
|          public void onClassified(SmartSelectionProvider.Result result) {
 | 
|              // If the selection does not exist any more, discard |result|.
 | 
| -            if (!mHasSelection) {
 | 
| +            if (!hasSelection()) {
 | 
|                  assert !mHidden;
 | 
|                  assert mClassificationResult == null;
 | 
|                  mPendingShowActionMode = false;
 | 
| 
 |