Remove secondary bidi cursor

The double bidi cursor is not user friendly. Almost no native speaker
of bidi languages likes the double cursor.

Now we always show one cursor.

Change-Id: I249befaf70630bef435c8db9039e8aacf233bf7c
Fixes: 63542996
Test: Manual (no more double cursors, bidi editing feels OK)
Test: bit CtsTextTestCases:*
Test: bit CtsWidgetTestCases:android.widget.cts.EditTextTest
Test: bit CtsWidgetTestCases:android.widget.cts.TextViewTest
Test: bit FrameworksCoreTests:android.text.
Test: bit FrameworksCoreTests:android.widget.EditorCursorTest
Test: bit FrameworksCoreTests:android.widget.TextViewTest
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 0d02444..02ead04 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -250,8 +250,7 @@
     SuggestionRangeSpan mSuggestionRangeSpan;
     private Runnable mShowSuggestionRunnable;
 
-    final Drawable[] mCursorDrawable = new Drawable[2];
-    int mCursorCount; // Current number of used mCursorDrawable: 0 (resource=0), 1 or 2 (split)
+    Drawable mCursorDrawable = null;
 
     private Drawable mSelectHandleLeft;
     private Drawable mSelectHandleRight;
@@ -1658,7 +1657,7 @@
             mCorrectionHighlighter.draw(canvas, cursorOffsetVertical);
         }
 
-        if (highlight != null && selectionStart == selectionEnd && mCursorCount > 0) {
+        if (highlight != null && selectionStart == selectionEnd && mCursorDrawable != null) {
             drawCursor(canvas, cursorOffsetVertical);
             // Rely on the drawable entirely, do not draw the cursor line.
             // Has to be done after the IMM related code above which relies on the highlight.
@@ -1849,8 +1848,8 @@
     private void drawCursor(Canvas canvas, int cursorOffsetVertical) {
         final boolean translate = cursorOffsetVertical != 0;
         if (translate) canvas.translate(0, cursorOffsetVertical);
-        for (int i = 0; i < mCursorCount; i++) {
-            mCursorDrawable[i].draw(canvas);
+        if (mCursorDrawable != null) {
+            mCursorDrawable.draw(canvas);
         }
         if (translate) canvas.translate(0, -cursorOffsetVertical);
     }
@@ -1907,32 +1906,20 @@
         }
     }
 
-    void updateCursorsPositions() {
+    void updateCursorPosition() {
         if (mTextView.mCursorDrawableRes == 0) {
-            mCursorCount = 0;
+            mCursorDrawable = null;
             return;
         }
 
-        Layout layout = mTextView.getLayout();
+        final Layout layout = mTextView.getLayout();
         final int offset = mTextView.getSelectionStart();
         final int line = layout.getLineForOffset(offset);
         final int top = layout.getLineTop(line);
         final int bottom = layout.getLineTop(line + 1);
 
-        mCursorCount = layout.isLevelBoundary(offset) ? 2 : 1;
-
-        int middle = bottom;
-        if (mCursorCount == 2) {
-            // Similar to what is done in {@link Layout.#getCursorPath(int, Path, CharSequence)}
-            middle = (top + bottom) >> 1;
-        }
-
-        boolean clamped = layout.shouldClampCursor(line);
-        updateCursorPosition(0, top, middle, layout.getPrimaryHorizontal(offset, clamped));
-
-        if (mCursorCount == 2) {
-            updateCursorPosition(1, middle, bottom, layout.getSecondaryHorizontal(offset, clamped));
-        }
+        final boolean clamped = layout.shouldClampCursor(line);
+        updateCursorPosition(top, bottom, layout.getPrimaryHorizontal(offset, clamped));
     }
 
     void refreshTextActionMode() {
@@ -2300,19 +2287,19 @@
     }
 
     @VisibleForTesting
-    public Drawable[] getCursorDrawable() {
+    @Nullable
+    public Drawable getCursorDrawable() {
         return mCursorDrawable;
     }
 
-    private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
-        if (mCursorDrawable[cursorIndex] == null) {
-            mCursorDrawable[cursorIndex] = mTextView.getContext().getDrawable(
+    private void updateCursorPosition(int top, int bottom, float horizontal) {
+        if (mCursorDrawable == null) {
+            mCursorDrawable = mTextView.getContext().getDrawable(
                     mTextView.mCursorDrawableRes);
         }
-        final Drawable drawable = mCursorDrawable[cursorIndex];
-        final int left = clampHorizontalPosition(drawable, horizontal);
-        final int width = drawable.getIntrinsicWidth();
-        drawable.setBounds(left, top - mTempRect.top, left + width,
+        final int left = clampHorizontalPosition(mCursorDrawable, horizontal);
+        final int width = mCursorDrawable.getIntrinsicWidth();
+        mCursorDrawable.setBounds(left, top - mTempRect.top, left + width,
                 bottom + mTempRect.bottom);
     }
 
@@ -4011,19 +3998,8 @@
                         mTextView.getSelectionStart(), mTextView.getSelectionEnd(), mSelectionPath);
                 mSelectionPath.computeBounds(mSelectionBounds, true);
                 mSelectionBounds.bottom += mHandleHeight;
-            } else if (mCursorCount == 2) {
-                // We have a split cursor. In this case, we take the rectangle that includes both
-                // parts of the cursor to ensure we don't obscure either of them.
-                Rect firstCursorBounds = mCursorDrawable[0].getBounds();
-                Rect secondCursorBounds = mCursorDrawable[1].getBounds();
-                mSelectionBounds.set(
-                        Math.min(firstCursorBounds.left, secondCursorBounds.left),
-                        Math.min(firstCursorBounds.top, secondCursorBounds.top),
-                        Math.max(firstCursorBounds.right, secondCursorBounds.right),
-                        Math.max(firstCursorBounds.bottom, secondCursorBounds.bottom)
-                                + mHandleHeight);
             } else {
-                // We have a single cursor.
+                // We have a cursor.
                 Layout layout = mTextView.getLayout();
                 int line = layout.getLineForOffset(mTextView.getSelectionStart());
                 float primaryHorizontal = clampHorizontalPosition(null,
@@ -4407,7 +4383,7 @@
         }
 
         /**
-         * Return the clamped horizontal position for the first cursor.
+         * Return the clamped horizontal position for the cursor.
          *
          * @param layout Text layout.
          * @param offset Character offset for the cursor.
@@ -4643,20 +4619,19 @@
         @Override
         protected int getCursorOffset() {
             int offset = super.getCursorOffset();
-            final Drawable cursor = mCursorCount > 0 ? mCursorDrawable[0] : null;
-            if (cursor != null) {
-                cursor.getPadding(mTempRect);
-                offset += (cursor.getIntrinsicWidth() - mTempRect.left - mTempRect.right) / 2;
+            if (mCursorDrawable != null) {
+                mCursorDrawable.getPadding(mTempRect);
+                offset += (mCursorDrawable.getIntrinsicWidth()
+                           - mTempRect.left - mTempRect.right) / 2;
             }
             return offset;
         }
 
         @Override
         int getCursorHorizontalPosition(Layout layout, int offset) {
-            final Drawable drawable = mCursorCount > 0 ? mCursorDrawable[0] : null;
-            if (drawable != null) {
+            if (mCursorDrawable != null) {
                 final float horizontal = getHorizontal(layout, offset);
-                return clampHorizontalPosition(drawable, horizontal) + mTempRect.left;
+                return clampHorizontalPosition(mCursorDrawable, horizontal) + mTempRect.left;
             }
             return super.getCursorHorizontalPosition(layout, offset);
         }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index aac609d..6a737cc 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6271,7 +6271,7 @@
             final int horizontalPadding = getCompoundPaddingLeft();
             final int verticalPadding = getExtendedPaddingTop() + getVerticalOffset(true);
 
-            if (mEditor.mCursorCount == 0) {
+            if (mEditor.mCursorDrawable == null) {
                 synchronized (TEMP_RECTF) {
                     /*
                      * The reason for this concern about the thickness of the
@@ -6298,11 +6298,9 @@
                             (int) Math.ceil(verticalPadding + TEMP_RECTF.bottom + thick));
                 }
             } else {
-                for (int i = 0; i < mEditor.mCursorCount; i++) {
-                    Rect bounds = mEditor.mCursorDrawable[i].getBounds();
-                    invalidate(bounds.left + horizontalPadding, bounds.top + verticalPadding,
-                            bounds.right + horizontalPadding, bounds.bottom + verticalPadding);
-                }
+                final Rect bounds = mEditor.mCursorDrawable.getBounds();
+                invalidate(bounds.left + horizontalPadding, bounds.top + verticalPadding,
+                        bounds.right + horizontalPadding, bounds.bottom + verticalPadding);
             }
         }
     }
@@ -6352,12 +6350,10 @@
             int bottom = mLayout.getLineBottom(lineEnd);
 
             // mEditor can be null in case selection is set programmatically.
-            if (invalidateCursor && mEditor != null) {
-                for (int i = 0; i < mEditor.mCursorCount; i++) {
-                    Rect bounds = mEditor.mCursorDrawable[i].getBounds();
-                    top = Math.min(top, bounds.top);
-                    bottom = Math.max(bottom, bounds.bottom);
-                }
+            if (invalidateCursor && mEditor != null && mEditor.mCursorDrawable != null) {
+                final Rect bounds = mEditor.mCursorDrawable.getBounds();
+                top = Math.min(top, bounds.top);
+                bottom = Math.max(bottom, bounds.bottom);
             }
 
             final int compoundPaddingLeft = getCompoundPaddingLeft();
@@ -6702,7 +6698,7 @@
                         if (mHighlightPath == null) mHighlightPath = new Path();
                         mHighlightPath.reset();
                         mLayout.getCursorPath(selStart, mHighlightPath, mText);
-                        mEditor.updateCursorsPositions();
+                        mEditor.updateCursorPosition();
                         mHighlightPathBogus = false;
                     }
 
diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java b/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
index 2532731..5ed69e0 100644
--- a/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
+++ b/core/tests/coretests/src/android/widget/espresso/TextViewAssertions.java
@@ -17,7 +17,9 @@
 package android.widget.espresso;
 
 import static android.support.test.espresso.matcher.ViewMatchers.assertThat;
+
 import static com.android.internal.util.Preconditions.checkNotNull;
+
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.number.IsCloseTo.closeTo;
 
@@ -33,6 +35,7 @@
 import android.widget.TextView;
 
 import junit.framework.AssertionFailedError;
+
 import org.hamcrest.Matcher;
 
 import java.lang.annotation.Retention;
@@ -202,7 +205,7 @@
                 throw new AssertionFailedError("View should be an instance of EditText");
             }
             EditText editText = (EditText) view;
-            Drawable drawable = editText.getEditorForTesting().getCursorDrawable()[0];
+            Drawable drawable = editText.getEditorForTesting().getCursorDrawable();
             Rect drawableBounds = drawable.getBounds();
             Rect drawablePadding = new Rect();
             drawable.getPadding(drawablePadding);