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

Commit 50f792e0 authored by czq's avatar czq
Browse files

Add a new API CursorAnchorInfo#getTextAppearanceInfo().

Add a new group of information related to text appearance in
CursorAnchorInfo, which is extracted from TextView.

Bug: 231894524

Test: atest android.view.inputmethod.cts.CursorAnchorInfoTest#testBuilder
atest android.view.inputmethod.cts.CursorAnchorInfoTest#testEquality
atest android.view.inputmethod.cts.InputMethodServiceTest#testOnUpdateCursorAnchorInfo

Change-Id: I8b96f055506b0a426dcfc6334db867dda7073868
parent d4e00f71
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -53245,6 +53245,7 @@ package android.view.inputmethod {
    method public android.graphics.Matrix getMatrix();
    method public int getSelectionEnd();
    method public int getSelectionStart();
    method @Nullable public android.view.inputmethod.TextAppearanceInfo getTextAppearanceInfo();
    method @NonNull public java.util.List<android.graphics.RectF> getVisibleLineBounds();
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.CursorAnchorInfo> CREATOR;
@@ -53265,6 +53266,7 @@ package android.view.inputmethod {
    method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, int);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
    method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
    method @NonNull public android.view.inputmethod.CursorAnchorInfo.Builder setTextAppearanceInfo(@Nullable android.view.inputmethod.TextAppearanceInfo);
  }
  public final class DeleteGesture extends android.view.inputmethod.HandwritingGesture implements android.os.Parcelable {
@@ -53519,6 +53521,7 @@ package android.view.inputmethod {
    field public static final int CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS = 8; // 0x8
    field public static final int CURSOR_UPDATE_FILTER_EDITOR_BOUNDS = 4; // 0x4
    field public static final int CURSOR_UPDATE_FILTER_INSERTION_MARKER = 16; // 0x10
    field public static final int CURSOR_UPDATE_FILTER_TEXT_APPEARANCE = 64; // 0x40
    field public static final int CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS = 32; // 0x20
    field public static final int CURSOR_UPDATE_IMMEDIATE = 1; // 0x1
    field public static final int CURSOR_UPDATE_MONITOR = 2; // 0x2
@@ -53822,6 +53825,35 @@ package android.view.inputmethod {
    field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.SurroundingText> CREATOR;
  }
  public final class TextAppearanceInfo implements android.os.Parcelable {
    ctor public TextAppearanceInfo(@NonNull android.widget.TextView);
    method public int describeContents();
    method @Nullable public String getFontFamilyName();
    method @Nullable public String getFontFeatureSettings();
    method @Nullable public String getFontVariationSettings();
    method public float getLetterSpacing();
    method public int getLineBreakStyle();
    method public int getLineBreakWordStyle();
    method public int getMaxLength();
    method @Px public float getShadowDx();
    method @Px public float getShadowDy();
    method @Px public float getShadowRadius();
    method @ColorInt public int getTextColor();
    method @ColorInt public int getTextColorHighlight();
    method @ColorInt public int getTextColorHint();
    method @Nullable public android.content.res.ColorStateList getTextColorLink();
    method @IntRange(from=0xffffffff, to=android.graphics.fonts.FontStyle.FONT_WEIGHT_MAX) public int getTextFontWeight();
    method @NonNull public android.os.LocaleList getTextLocales();
    method public float getTextScaleX();
    method @Px public float getTextSize();
    method public int getTextStyle();
    method public boolean isAllCaps();
    method public boolean isElegantTextHeight();
    method public boolean isFallbackLineSpacing();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.TextAppearanceInfo> CREATOR;
  }
  public final class TextAttribute implements android.os.Parcelable {
    method public int describeContents();
    method @NonNull public android.os.PersistableBundle getExtras();
+50 −8
Original line number Diff line number Diff line
@@ -20,12 +20,14 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.inputmethodservice.InputMethodService;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.Layout;
import android.text.SpannedString;
import android.text.TextUtils;
import android.view.inputmethod.SparseRectFArray.SparseRectFArrayBuilder;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Arrays;
@@ -110,7 +112,7 @@ public final class CursorAnchorInfo implements Parcelable {
    /**
     * Container of rectangular position of Editor in the local coordinates that will be transformed
     * with the transformation matrix when rendered on the screen.
     * @see {@link EditorBoundsInfo}.
     * @see EditorBoundsInfo
     */
    private final EditorBoundsInfo mEditorBoundsInfo;

@@ -121,6 +123,12 @@ public final class CursorAnchorInfo implements Parcelable {
    @NonNull
    private final float[] mMatrixValues;

    /**
     * Information about text appearance in the editor for use by {@link InputMethodService}.
     */
    @Nullable
    private final TextAppearanceInfo mTextAppearanceInfo;

    /**
     * A list of visible line bounds stored in a float array. This array is divided into segment of
     * four where each element in the segment represents left, top, right respectively and bottom
@@ -157,10 +165,11 @@ public final class CursorAnchorInfo implements Parcelable {
        mInsertionMarkerTop = source.readFloat();
        mInsertionMarkerBaseline = source.readFloat();
        mInsertionMarkerBottom = source.readFloat();
        mCharacterBoundsArray = source.readParcelable(SparseRectFArray.class.getClassLoader(), android.view.inputmethod.SparseRectFArray.class);
        mCharacterBoundsArray = source.readTypedObject(SparseRectFArray.CREATOR);
        mEditorBoundsInfo = source.readTypedObject(EditorBoundsInfo.CREATOR);
        mMatrixValues = source.createFloatArray();
        mVisibleLineBounds = source.createFloatArray();
        mTextAppearanceInfo = source.readTypedObject(TextAppearanceInfo.CREATOR);
    }

    /**
@@ -181,10 +190,11 @@ public final class CursorAnchorInfo implements Parcelable {
        dest.writeFloat(mInsertionMarkerTop);
        dest.writeFloat(mInsertionMarkerBaseline);
        dest.writeFloat(mInsertionMarkerBottom);
        dest.writeParcelable(mCharacterBoundsArray, flags);
        dest.writeTypedObject(mCharacterBoundsArray, flags);
        dest.writeTypedObject(mEditorBoundsInfo, flags);
        dest.writeFloatArray(mMatrixValues);
        dest.writeFloatArray(mVisibleLineBounds);
        dest.writeTypedObject(mTextAppearanceInfo, flags);
    }

    @Override
@@ -262,6 +272,11 @@ public final class CursorAnchorInfo implements Parcelable {
                return false;
            }
        }

        if (!Objects.equals(mTextAppearanceInfo, that.mTextAppearanceInfo)) {
            return false;
        }

        return true;
    }

@@ -270,16 +285,17 @@ public final class CursorAnchorInfo implements Parcelable {
        return "CursorAnchorInfo{mHashCode=" + mHashCode
                + " mSelection=" + mSelectionStart + "," + mSelectionEnd
                + " mComposingTextStart=" + mComposingTextStart
                + " mComposingText=" + Objects.toString(mComposingText)
                + " mComposingText=" + mComposingText
                + " mInsertionMarkerFlags=" + mInsertionMarkerFlags
                + " mInsertionMarkerHorizontal=" + mInsertionMarkerHorizontal
                + " mInsertionMarkerTop=" + mInsertionMarkerTop
                + " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline
                + " mInsertionMarkerBottom=" + mInsertionMarkerBottom
                + " mCharacterBoundsArray=" + Objects.toString(mCharacterBoundsArray)
                + " mCharacterBoundsArray=" + mCharacterBoundsArray
                + " mEditorBoundsInfo=" + mEditorBoundsInfo
                + " mVisibleLineBounds=" + getVisibleLineBounds()
                + " mMatrix=" + Arrays.toString(mMatrixValues)
                + " mTextAppearanceInfo=" + mTextAppearanceInfo
                + "}";
    }

@@ -303,6 +319,7 @@ public final class CursorAnchorInfo implements Parcelable {
        private boolean mMatrixInitialized = false;
        private float[] mVisibleLineBounds = new float[LINE_BOUNDS_INITIAL_SIZE * 4];
        private int mVisibleLineBoundsCount = 0;
        private TextAppearanceInfo mTextAppearanceInfo = null;

        /**
         * Sets the text range of the selection. Calling this can be skipped if there is no
@@ -415,6 +432,17 @@ public final class CursorAnchorInfo implements Parcelable {
            return this;
        }

        /**
         * Set the information related to text appearance, which is extracted from the original
         * {@link TextView}.
         * @param textAppearanceInfo {@link TextAppearanceInfo} of TextView.
         */
        @NonNull
        public Builder setTextAppearanceInfo(@Nullable TextAppearanceInfo textAppearanceInfo) {
            mTextAppearanceInfo = textAppearanceInfo;
            return this;
        }

        /**
         * Add the bounds of a visible text line of the current editor.
         *
@@ -504,6 +532,7 @@ public final class CursorAnchorInfo implements Parcelable {
            }
            mEditorBoundsInfo = null;
            clearVisibleLineBounds();
            mTextAppearanceInfo = null;
        }
    }

@@ -524,7 +553,8 @@ public final class CursorAnchorInfo implements Parcelable {
                builder.mInsertionMarkerHorizontal, builder.mInsertionMarkerTop,
                builder.mInsertionMarkerBaseline, builder.mInsertionMarkerBottom,
                characterBoundsArray, builder.mEditorBoundsInfo, matrixValues,
                Arrays.copyOf(builder.mVisibleLineBounds, builder.mVisibleLineBoundsCount));
                Arrays.copyOf(builder.mVisibleLineBounds, builder.mVisibleLineBoundsCount),
                builder.mTextAppearanceInfo);
    }

    private CursorAnchorInfo(int selectionStart, int selectionEnd, int composingTextStart,
@@ -533,7 +563,8 @@ public final class CursorAnchorInfo implements Parcelable {
            float insertionMarkerBaseline, float insertionMarkerBottom,
            @Nullable SparseRectFArray characterBoundsArray,
            @Nullable EditorBoundsInfo editorBoundsInfo,
            @NonNull float[] matrixValues, @Nullable float[] visibleLineBounds) {
            @NonNull float[] matrixValues, @Nullable float[] visibleLineBounds,
            @Nullable TextAppearanceInfo textAppearanceInfo) {
        mSelectionStart = selectionStart;
        mSelectionEnd = selectionEnd;
        mComposingTextStart = composingTextStart;
@@ -547,6 +578,7 @@ public final class CursorAnchorInfo implements Parcelable {
        mEditorBoundsInfo = editorBoundsInfo;
        mMatrixValues = matrixValues;
        mVisibleLineBounds = visibleLineBounds;
        mTextAppearanceInfo = textAppearanceInfo;

        // To keep hash function simple, we only use some complex objects for hash.
        int hashCode = Objects.hashCode(mComposingText);
@@ -573,7 +605,7 @@ public final class CursorAnchorInfo implements Parcelable {
                original.mInsertionMarkerTop, original.mInsertionMarkerBaseline,
                original.mInsertionMarkerBottom, original.mCharacterBoundsArray,
                original.mEditorBoundsInfo, computeMatrixValues(parentMatrix, original),
                original.mVisibleLineBounds);
                original.mVisibleLineBounds, original.mTextAppearanceInfo);
    }

    /**
@@ -740,6 +772,16 @@ public final class CursorAnchorInfo implements Parcelable {
        return mEditorBoundsInfo;
    }

    /**
     * Returns {@link TextAppearanceInfo} for the current editor, or {@code null} if IME is not
     * subscribed with {@link InputConnection#CURSOR_UPDATE_FILTER_TEXT_APPEARANCE}
     * or {@link InputConnection#CURSOR_UPDATE_MONITOR}.
     */
    @Nullable
    public TextAppearanceInfo getTextAppearanceInfo() {
        return mTextAppearanceInfo;
    }

    /**
     * Returns a new instance of {@link android.graphics.Matrix} that indicates the transformation
     * matrix that is to be applied other positional data in this class.
+31 −11
Original line number Diff line number Diff line
@@ -1052,8 +1052,10 @@ public interface InputConnection {
     * used together with {@link #CURSOR_UPDATE_MONITOR}.
     * <p>
     * Note by default all of {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS} and
     * {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER} are included but specifying them can
     * {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_TEXT_APPEARANCE}, and
     * {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER}, are included but specifying them can
     * filter-out others.
     * It can be CPU intensive to include all, filtering specific info is recommended.
     * </p>
@@ -1071,7 +1073,8 @@ public interface InputConnection {
     * <p>
     * Note by default all of {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS} and
     * {@link #CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_TEXT_APPEARANCE}, and
     * {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER}, are included but specifying them can
     * filter-out others.
     * It can be CPU intensive to include all, filtering specific info is recommended.
@@ -1087,6 +1090,7 @@ public interface InputConnection {
     * <p>
     * This flag can be used together with filters: {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_TEXT_APPEARANCE},
     * {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER} and update flags
     * {@link #CURSOR_UPDATE_IMMEDIATE} and {@link #CURSOR_UPDATE_MONITOR}.
     * </p>
@@ -1102,8 +1106,8 @@ public interface InputConnection {
     * <p>
     * This flag can be combined with other filters: {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER} and update flags
     * {@link #CURSOR_UPDATE_IMMEDIATE} and {@link #CURSOR_UPDATE_MONITOR}.
     * {@link #CURSOR_UPDATE_FILTER_TEXT_APPEARANCE}, {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER}
     * and update flags {@link #CURSOR_UPDATE_IMMEDIATE} and {@link #CURSOR_UPDATE_MONITOR}.
     * </p>
     */
    int CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS = 1 << 3;
@@ -1118,8 +1122,8 @@ public interface InputConnection {
     * <p>
     * This flag can be combined with other filters: {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS} and update flags {@link #CURSOR_UPDATE_IMMEDIATE}
     * and {@link #CURSOR_UPDATE_MONITOR}.
     * {@link #CURSOR_UPDATE_FILTER_TEXT_APPEARANCE}, {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS}
     * and update flags {@link #CURSOR_UPDATE_IMMEDIATE} and {@link #CURSOR_UPDATE_MONITOR}.
     * </p>
     */
    int CURSOR_UPDATE_FILTER_INSERTION_MARKER = 1 << 4;
@@ -1133,13 +1137,28 @@ public interface InputConnection {
     * {@link InputConnection#requestCursorUpdates(int)} again with this flag off.
     * <p>
     * This flag can be combined with other filters: {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS}, {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER}
     * and update flags {@link #CURSOR_UPDATE_IMMEDIATE}
     * and {@link #CURSOR_UPDATE_MONITOR}.
     * {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS}, {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER},
     * {@link #CURSOR_UPDATE_FILTER_TEXT_APPEARANCE} and update flags
     * {@link #CURSOR_UPDATE_IMMEDIATE} and {@link #CURSOR_UPDATE_MONITOR}.
     * </p>
     */
    int CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS = 1 << 5;

    /**
     * The editor is requested to call
     * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)}
     * with new text appearance info {@link CursorAnchorInfo#getTextAppearanceInfo()}}
     * whenever cursor/anchor position is changed. To disable monitoring, call
     * {@link InputConnection#requestCursorUpdates(int)} again with this flag off.
     * <p>
     * This flag can be combined with other filters: {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS},
     * {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS}, {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER},
     * {@link #CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS} and update flags
     * {@link #CURSOR_UPDATE_IMMEDIATE} and {@link #CURSOR_UPDATE_MONITOR}.
     * </p>
     */
    int CURSOR_UPDATE_FILTER_TEXT_APPEARANCE = 1 << 6;

    /**
     * @hide
     */
@@ -1153,7 +1172,8 @@ public interface InputConnection {
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(value = {CURSOR_UPDATE_FILTER_EDITOR_BOUNDS, CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS,
            CURSOR_UPDATE_FILTER_INSERTION_MARKER, CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS},
            CURSOR_UPDATE_FILTER_INSERTION_MARKER, CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS,
            CURSOR_UPDATE_FILTER_TEXT_APPEARANCE},
            flag = true, prefix = { "CURSOR_UPDATE_FILTER_" })
    @interface CursorUpdateFilter{}

+509 −0

File added.

Preview size limit exceeded, changes collapsed.

+9 −1
Original line number Diff line number Diff line
@@ -125,6 +125,7 @@ import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.TextAppearanceInfo;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassificationManager;
import android.widget.AdapterView.OnItemClickListener;
@@ -4630,14 +4631,17 @@ public class Editor {
                    (filter & InputConnection.CURSOR_UPDATE_FILTER_INSERTION_MARKER) != 0;
            boolean includeVisibleLineBounds =
                    (filter & InputConnection.CURSOR_UPDATE_FILTER_VISIBLE_LINE_BOUNDS) != 0;
            boolean includeTextAppearance =
                    (filter & InputConnection.CURSOR_UPDATE_FILTER_TEXT_APPEARANCE) != 0;
            boolean includeAll =
                    (!includeEditorBounds && !includeCharacterBounds && !includeInsertionMarker
                    && !includeVisibleLineBounds);
                    && !includeVisibleLineBounds && !includeTextAppearance);

            includeEditorBounds |= includeAll;
            includeCharacterBounds |= includeAll;
            includeInsertionMarker |= includeAll;
            includeVisibleLineBounds |= includeAll;
            includeTextAppearance |= includeAll;

            final CursorAnchorInfo.Builder builder = mSelectionInfoBuilder;
            builder.reset();
@@ -4757,6 +4761,10 @@ public class Editor {
                }
            }

            if (includeTextAppearance) {
                TextAppearanceInfo textAppearanceInfo = new TextAppearanceInfo(mTextView);
                builder.setTextAppearanceInfo(textAppearanceInfo);
            }
            imm.updateCursorAnchorInfo(mTextView, builder.build());

            // Drop the immediate flag if any.
Loading