Long press with trackball selects word under cursor.

Bug 3068305

Change-Id: Ib37fc98a61efdf3fbfccbb2174e2dbdbcb1a240e
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 548002f..d1974dc 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4321,6 +4321,7 @@
 
         switch (keyCode) {
             case KeyEvent.KEYCODE_ENTER:
+                mEnterKeyIsDown = true;
                 // If ALT modifier is held, then we always insert a
                 // newline character.
                 if ((event.getMetaState()&KeyEvent.META_ALT_ON) == 0) {
@@ -4353,6 +4354,7 @@
                 break;
                 
             case KeyEvent.KEYCODE_DPAD_CENTER:
+                mDPadCenterIsDown = true;
                 if (shouldAdvanceFocusOnEnter()) {
                     return 0;
                 }
@@ -4447,6 +4449,7 @@
 
         switch (keyCode) {
             case KeyEvent.KEYCODE_DPAD_CENTER:
+                mDPadCenterIsDown = false;
                 /*
                  * If there is a click listener, just call through to
                  * super, which will invoke it.
@@ -4467,6 +4470,7 @@
                 return super.onKeyUp(keyCode, event);
                 
             case KeyEvent.KEYCODE_ENTER:
+                mEnterKeyIsDown = false;
                 if (mInputContentType != null
                         && mInputContentType.onEditorActionListener != null
                         && mInputContentType.enterDown) {
@@ -7249,13 +7253,20 @@
             return;
         }
 
-        int selectionStart, selectionEnd;
+        int minOffset, maxOffset;
 
-        // selectionModifierCursorController is not null at that point
-        SelectionModifierCursorController selectionModifierCursorController =
-            ((SelectionModifierCursorController) mSelectionModifierCursorController);
-        int minOffset = selectionModifierCursorController.getMinTouchOffset();
-        int maxOffset = selectionModifierCursorController.getMaxTouchOffset();
+        if (mDPadCenterIsDown || mEnterKeyIsDown) {
+            minOffset = getSelectionStart();
+            maxOffset = getSelectionEnd();
+        } else {
+            // selectionModifierCursorController is not null at that point
+            SelectionModifierCursorController selectionModifierCursorController =
+                ((SelectionModifierCursorController) mSelectionModifierCursorController);
+            minOffset = selectionModifierCursorController.getMinTouchOffset();
+            maxOffset = selectionModifierCursorController.getMaxTouchOffset();
+        }
+
+        int selectionStart, selectionEnd;
         
         long wordLimits = getWordLimitsAt(minOffset);
         if (wordLimits >= 0) {
@@ -7275,11 +7286,7 @@
     }
     
     private String getWordForDictionary() {
-        if (mLastTouchOffset < 0) {
-            return null;
-        }
-
-        long wordLimits = getWordLimitsAt(mLastTouchOffset);
+        long wordLimits = getWordLimitsAt(getSelectionStart());
         if (wordLimits >= 0) {
             int start = extractRangeStartFromLong(wordLimits);
             int end = extractRangeEndFromLong(wordLimits);
@@ -7881,8 +7888,7 @@
                 final float newPosX = rawX - mTouchToWindowOffsetX + mHotspotX;
                 final float newPosY = rawY - mTouchToWindowOffsetY + mHotspotY + mTouchOffsetY;
 
-                mController.updatePosition(this, (int) Math.round(newPosX),
-                        (int) Math.round(newPosY));
+                mController.updatePosition(this, Math.round(newPosX), Math.round(newPosY));
 
                 break;
             }
@@ -8254,6 +8260,10 @@
     private CursorController        mSelectionModifierCursorController;
     private boolean                 mIsInTextSelectionMode = false;
     private int                     mLastTouchOffset = -1;
+    // These are needed to desambiguate a long click. If the long click comes from ones of these, we
+    // select from the current cursor position. Otherwise, select from long pressed position.
+    private boolean                 mDPadCenterIsDown = false;
+    private boolean                 mEnterKeyIsDown = false;
     // Created once and shared by different CursorController helper methods.
     // Only one cursor controller is active at any time which prevent race conditions.
     private static Rect             sCursorControllerTempRect = new Rect();