Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9edfec8b authored by Yohei Yukawa's avatar Yohei Yukawa Committed by Android (Google) Code Review
Browse files

Merge "Enable CursorAnchorInfo to contain composing string"

parents 2c5d9787 81f4cb3f
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -33574,9 +33574,9 @@ package android.view.inputmethod {
  public final class CursorAnchorInfo implements android.os.Parcelable {
    ctor public CursorAnchorInfo(android.os.Parcel);
    method public int describeContents();
    method public int getCandidatesEnd();
    method public int getCandidatesStart();
    method public android.graphics.RectF getCharacterRect(int);
    method public java.lang.String getComposingText();
    method public int getComposingTextStart();
    method public float getInsertionMarkerBaseline();
    method public float getInsertionMarkerBottom();
    method public float getInsertionMarkerHorizontal();
@@ -33593,7 +33593,7 @@ package android.view.inputmethod {
    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder addCharacterRect(int, float, float, float, float);
    method public android.view.inputmethod.CursorAnchorInfo build();
    method public void reset();
    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setCandidateRange(int, int);
    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setComposingText(int, java.lang.CharSequence);
    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setInsertionMarkerLocation(float, float, float, float);
    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setMatrix(android.graphics.Matrix);
    method public android.view.inputmethod.CursorAnchorInfo.CursorAnchorInfoBuilder setSelectionRange(int, int);
+54 −37
Original line number Diff line number Diff line
@@ -35,8 +35,12 @@ import java.util.Objects;
public final class CursorAnchorInfo implements Parcelable {
    private final int mSelectionStart;
    private final int mSelectionEnd;
    private final int mCandidatesStart;
    private final int mCandidatesEnd;

    private final int mComposingTextStart;
    /**
     * The text, tracked as a composing region.
     */
    private final String mComposingText;

    /**
     * Horizontal position of the insertion marker, in the local coordinates that will be
@@ -83,8 +87,8 @@ public final class CursorAnchorInfo implements Parcelable {
    public CursorAnchorInfo(final Parcel source) {
        mSelectionStart = source.readInt();
        mSelectionEnd = source.readInt();
        mCandidatesStart = source.readInt();
        mCandidatesEnd = source.readInt();
        mComposingTextStart = source.readInt();
        mComposingText = source.readString();
        mInsertionMarkerHorizontal = source.readFloat();
        mInsertionMarkerTop = source.readFloat();
        mInsertionMarkerBaseline = source.readFloat();
@@ -104,8 +108,8 @@ public final class CursorAnchorInfo implements Parcelable {
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mSelectionStart);
        dest.writeInt(mSelectionEnd);
        dest.writeInt(mCandidatesStart);
        dest.writeInt(mCandidatesEnd);
        dest.writeInt(mComposingTextStart);
        dest.writeString(mComposingText);
        dest.writeFloat(mInsertionMarkerHorizontal);
        dest.writeFloat(mInsertionMarkerTop);
        dest.writeFloat(mInsertionMarkerBaseline);
@@ -119,14 +123,17 @@ public final class CursorAnchorInfo implements Parcelable {
    @Override
    public int hashCode(){
        // TODO: Improve the hash function.
        final float floatHash = mSelectionStart + mSelectionEnd + mCandidatesStart + mCandidatesEnd
                + mInsertionMarkerHorizontal + mInsertionMarkerTop + mInsertionMarkerBaseline
                + mInsertionMarkerBottom;
        final float floatHash = mInsertionMarkerHorizontal + mInsertionMarkerTop
                + mInsertionMarkerBaseline + mInsertionMarkerBottom;
        int hash = floatHash > 0 ? (int) floatHash : (int)(-floatHash);
        if (mCharacterRects != null) {
            hash += mCharacterRects.hashCode();
        }
        hash += mMatrix.hashCode();
        hash *= 31;
        hash += mSelectionStart + mSelectionEnd + mComposingTextStart;
        hash *= 31;
        hash += Objects.hashCode(mComposingText);
        hash *= 31;
        hash += Objects.hashCode(mCharacterRects);
        hash *= 31;
        hash += Objects.hashCode(mMatrix);
        return hash;
    }

@@ -147,8 +154,10 @@ public final class CursorAnchorInfo implements Parcelable {
        }
        if (mSelectionStart != that.mSelectionStart
                || mSelectionEnd != that.mSelectionEnd
                || mCandidatesStart != that.mCandidatesStart
                || mCandidatesEnd != that.mCandidatesEnd) {
                || mComposingTextStart != that.mComposingTextStart) {
            return false;
        }
        if (!Objects.equals(mComposingTextStart, that.mComposingTextStart)) {
            return false;
        }
        if (!Objects.equals(mCharacterRects, that.mCharacterRects)) {
@@ -163,13 +172,14 @@ public final class CursorAnchorInfo implements Parcelable {
    @Override
    public String toString() {
        return "SelectionInfo{mSelection=" + mSelectionStart + "," + mSelectionEnd
                + " mCandiadtes=" + mCandidatesStart + "," + mCandidatesEnd
                + " mComposingTextStart=" + mComposingTextStart
                + " mComposingText=" + Objects.toString(mComposingText)
                + " mInsertionMarkerHorizontal=" + mInsertionMarkerHorizontal
                + " mInsertionMarkerTop=" + mInsertionMarkerTop
                + " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline
                + " mInsertionMarkerBottom=" + mInsertionMarkerBottom
                + " mCharacterRects=" + (mCharacterRects != null ? mCharacterRects : "null")
                + " mMatrix=" + mMatrix
                + " mCharacterRects=" + Objects.toString(mCharacterRects)
                + " mMatrix=" + Objects.toString(mMatrix)
                + "}";
    }

@@ -190,16 +200,23 @@ public final class CursorAnchorInfo implements Parcelable {
        private int mSelectionEnd = -1;

        /**
         * Sets the text range of the composition string. Calling this can be skipped if there is
         * no composition.
         * Sets the text range of the composing text. Calling this can be skipped if there is
         * no composing text.
         * @param index index where the composing text starts.
         * @param composingText the entire composing text.
         */
        public CursorAnchorInfoBuilder setCandidateRange(final int start, final int end) {
            mCandidateStart = start;
            mCandidateEnd = end;
        public CursorAnchorInfoBuilder setComposingText(final int index,
                final CharSequence composingText) {
            mComposingTextStart = index;
            if (composingText == null) {
                mComposingText = null;
            } else {
                mComposingText = composingText.toString();
            }
            return this;
        }
        private int mCandidateStart = -1;
        private int mCandidateEnd = -1;
        private int mComposingTextStart = -1;
        private String mComposingText = null;

        /**
         * Sets the location of the text insertion point (zero width cursor) as a rectangle in
@@ -297,8 +314,8 @@ public final class CursorAnchorInfo implements Parcelable {
        public void reset() {
            mSelectionStart = -1;
            mSelectionEnd = -1;
            mCandidateStart = -1;
            mCandidateEnd = -1;
            mComposingTextStart = -1;
            mComposingText = null;
            mInsertionMarkerHorizontal = Float.NaN;
            mInsertionMarkerTop = Float.NaN;
            mInsertionMarkerBaseline = Float.NaN;
@@ -313,8 +330,8 @@ public final class CursorAnchorInfo implements Parcelable {
    private CursorAnchorInfo(final CursorAnchorInfoBuilder builder) {
        mSelectionStart = builder.mSelectionStart;
        mSelectionEnd = builder.mSelectionEnd;
        mCandidatesStart = builder.mCandidateStart;
        mCandidatesEnd = builder.mCandidateEnd;
        mComposingTextStart = builder.mComposingTextStart;
        mComposingText = builder.mComposingText;
        mInsertionMarkerHorizontal = builder.mInsertionMarkerHorizontal;
        mInsertionMarkerTop = builder.mInsertionMarkerTop;
        mInsertionMarkerBaseline = builder.mInsertionMarkerBaseline;
@@ -341,19 +358,19 @@ public final class CursorAnchorInfo implements Parcelable {
    }

    /**
     * Returns the index where the composition starts.
     * @return -1 if there is no composition.
     * Returns the index where the composing text starts.
     * @return -1 if there is no composing text.
     */
    public int getCandidatesStart() {
        return mCandidatesStart;
    public int getComposingTextStart() {
        return mComposingTextStart;
    }

    /**
     * Returns the index where the composition ends.
     * @return -1 if there is no composition.
     * Returns the entire composing text.
     * @return null if there is no composition.
     */
    public int getCandidatesEnd() {
        return mCandidatesEnd;
    public String getComposingText() {
        return mComposingText;
    }

    /**
+18 −12
Original line number Diff line number Diff line
@@ -3041,8 +3041,7 @@ public class Editor {
            builder.reset();

            final int selectionStart = mTextView.getSelectionStart();
            final int selectionEnd = mTextView.getSelectionEnd();
            builder.setSelectionRange(mTextView.getSelectionStart(), mTextView.getSelectionEnd());
            builder.setSelectionRange(selectionStart, mTextView.getSelectionEnd());

            // Construct transformation matrix from view local coordinates to screen coordinates.
            mViewToScreenMatrix.set(mTextView.getMatrix());
@@ -3055,17 +3054,24 @@ public class Editor {
            final float viewportToContentVerticalOffset =
                    mTextView.viewportToContentVerticalOffset();

            if (mTextView.getText() instanceof Spannable) {
                final Spannable sp = (Spannable) mTextView.getText();
                int compositionStart = EditableInputConnection.getComposingSpanStart(sp);
                int compositionEnd = EditableInputConnection.getComposingSpanEnd(sp);
                if (compositionEnd < compositionStart) {
                    final int temp = compositionEnd;
                    compositionEnd = compositionStart;
                    compositionStart = temp;
                }
                builder.setCandidateRange(compositionStart, compositionEnd);
                for (int offset = compositionStart; offset < compositionEnd; offset++) {
            final CharSequence text = mTextView.getText();
            if (text instanceof Spannable) {
                final Spannable sp = (Spannable) text;
                int composingTextStart = EditableInputConnection.getComposingSpanStart(sp);
                int composingTextEnd = EditableInputConnection.getComposingSpanEnd(sp);
                if (composingTextEnd < composingTextStart) {
                    final int temp = composingTextEnd;
                    composingTextEnd = composingTextStart;
                    composingTextStart = temp;
                }
                final boolean hasComposingText =
                        (0 <= composingTextStart) && (composingTextStart < composingTextEnd);
                if (hasComposingText) {
                    final CharSequence composingText = text.subSequence(composingTextStart,
                            composingTextEnd);
                    builder.setComposingText(composingTextStart, composingText);
                }
                for (int offset = composingTextStart; offset < composingTextEnd; offset++) {
                    if (offset < 0) {
                        continue;
                    }
+14 −12
Original line number Diff line number Diff line
@@ -52,18 +52,21 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
    public void testBuilder() throws Exception {
        final int SELECTION_START = 30;
        final int SELECTION_END = 40;
        final int CANDIDATES_START = 32;
        final int CANDIDATES_END = 33;
        final int COMPOSING_TEXT_START = 32;
        final String COMPOSING_TEXT = "test";
        final float INSERTION_MARKER_HORIZONTAL = 10.5f;
        final float INSERTION_MARKER_TOP = 100.1f;
        final float INSERTION_MARKER_BASELINE = 110.4f;
        final float INSERTION_MARKER_BOTOM = 111.0f;
        final int CHAR_INDEX = 32;
        final char CHAR_VALUE = 'X';
        final char DEFAULT_CHAR_VALUE = '!';
        Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
        TRANSFORM_MATRIX.setScale(10.0f, 20.0f);

        final CursorAnchorInfoBuilder builder = new CursorAnchorInfoBuilder();
        builder.setSelectionRange(SELECTION_START, SELECTION_END)
                .setCandidateRange(CANDIDATES_START, CANDIDATES_END)
                .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT)
                .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
                        INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM)
                .setMatrix(TRANSFORM_MATRIX);
@@ -77,8 +80,8 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
        final CursorAnchorInfo info = builder.build();
        assertEquals(SELECTION_START, info.getSelectionStart());
        assertEquals(SELECTION_END, info.getSelectionEnd());
        assertEquals(CANDIDATES_START, info.getCandidatesStart());
        assertEquals(CANDIDATES_END, info.getCandidatesEnd());
        assertEquals(COMPOSING_TEXT_START, info.getComposingTextStart());
        assertEquals(COMPOSING_TEXT, info.getComposingText());
        assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal());
        assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop());
        assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline());
@@ -93,8 +96,8 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
        final CursorAnchorInfo info2 = builder.build();
        assertEquals(SELECTION_START, info2.getSelectionStart());
        assertEquals(SELECTION_END, info2.getSelectionEnd());
        assertEquals(CANDIDATES_START, info2.getCandidatesStart());
        assertEquals(CANDIDATES_END, info2.getCandidatesEnd());
        assertEquals(COMPOSING_TEXT_START, info2.getComposingTextStart());
        assertEquals(COMPOSING_TEXT, info2.getComposingText());
        assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal());
        assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop());
        assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline());
@@ -111,8 +114,8 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
        final CursorAnchorInfo info3 = cloneViaParcel(info2);
        assertEquals(SELECTION_START, info3.getSelectionStart());
        assertEquals(SELECTION_END, info3.getSelectionEnd());
        assertEquals(CANDIDATES_START, info3.getCandidatesStart());
        assertEquals(CANDIDATES_END, info3.getCandidatesEnd());
        assertEquals(COMPOSING_TEXT_START, info3.getComposingTextStart());
        assertEquals(COMPOSING_TEXT, info3.getComposingText());
        assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal());
        assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop());
        assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline());
@@ -128,13 +131,12 @@ public class CursorAnchorInfoTest extends InstrumentationTestCase {
        final CursorAnchorInfo uninitializedInfo = builder.build();
        assertEquals(-1, uninitializedInfo.getSelectionStart());
        assertEquals(-1, uninitializedInfo.getSelectionEnd());
        assertEquals(-1, uninitializedInfo.getCandidatesStart());
        assertEquals(-1, uninitializedInfo.getCandidatesEnd());
        assertEquals(-1, uninitializedInfo.getComposingTextStart());
        assertNull(uninitializedInfo.getComposingText());
        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerHorizontal());
        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop());
        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline());
        assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBottom());
        assertEquals(Matrix.IDENTITY_MATRIX, uninitializedInfo.getMatrix());
    }

    @SmallTest